MVC نموذج ملزم قبل KnockoutJS نموذج ملزم

لذا إذا كانت وحدة تحكم الإجراء الخاصة بك تقوم بإرجاع نموذج مع قيم مملوءة مسبقًا ، فكيف يمكنك معرفة KnockoutJS بها؟

على سبيل المثال:

@Html.TextBoxFor(m => m.Title, new { data_bind="value: title"} )

ومع ذلك ، على $ (document). ready() حيث أقوم بربط knockout.js ViewModel ، لا يتم نشر هذه القيمة بعد:

$(document).ready({
  var viewModel = {
    title: ko.observable($("#Title").val())//too early for this?!
  }

  ko.applyBindings(viewModel);​
});

كيف تعمل KnockoutJS مع نموذج ملزمة MVC؟ كان أحد الحلول التي وجدتها هو تعيين متغير جافا سكريبت في طريقة عرض Razor ، مثل:

<script>
  var strTitle = '@Model.Title';
</script>

واستخدمها في ربط نموذج Knockout. هذا يعمل ، لكني أكره ذلك. ماذا لو كان نموذجك يشبه المئات من الحقول؟ أنت لا تريد العديد من متغيرات جافا سكريبت في صفحتك. هل أفتقد الواضح هنا؟

0

3 إجابة

يبدو هذا مشابهًا لـ هذا السؤال . عادةً ما تقوم بتعيين نموذج العرض الخاص بك عن طريق تحويلModel إلى JSON في برنامج نصي:

<script type="text/javascript">
var model = @(new HtmlString(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model)));
</script>

يمكنك أيضًا إنشاء معالج الربط الخاص بك الذي سيقوم في البداية بتحميل نموذج العرض استنادًا إلى قيم التحكم. يقوم هذا المعالج الجديد myvalue بشكل أساسي باستدعاء معالج القيمة الموجود ، باستثناء أنه يقوم بتحديث نموذج العرض من قيمة عنصر التحكم الأولي في init.

ko.bindingHandlers['myvalue'] = {
    'init': function (element, valueAccessor, allBindingsAccessor) {
       //call existing value init code
        ko.bindingHandlers['value'].init(element, valueAccessor, allBindingsAccessor);

       //valueUpdateHandler() code
        var modelValue = valueAccessor();
        var elementValue = ko.selectExtensions.readValue(element);
        modelValue(elementValue);//simplified next line, writeValueToProperty isn't exported
        //ko.jsonExpressionRewriting.writeValueToProperty(modelValue, allBindingsAccessor, 'value', elementValue, /* checkIfDifferent: */ true);
    },
    'update': function (element, valueAccessor) {
       //call existing value update code
        ko.bindingHandlers['value'].update(element, valueAccessor);
    }
};

عند الاتصال بـ ko.applyBindings ، سيتم تعيين ملاحظتك استنادًا إلى قيمة عنصر التحكم في البداية:

<input type="text" data-bind="myvalue: Title" value="This Title will be used" />
<input type="text" data-bind="value: Title" value="This will not be used" />
<!-- MVC -->
@Html.TextBoxFor(m => m.Title, new { data_bind="myvalue: Title"} )

SAMPLE FIDDLE

0
وأضاف
Tsar - لقد قمت بتحديث الإجابة للحصول عليها للعمل وأعطت مثالًا كمانًا ، فإن وظيفة ko.jsonExpressionRewriting.writeValueToProperty لم يتم تصديرها وعملت فقط مع إصدار debug من knockout ، غيرت ذلك إلى مكالمة أبسط يجب أن تعمل طويلاً كما العنوان هو ملاحظتها.
وأضاف المؤلف Jason Goemaat, مصدر
شكرا ، للأسف هذا لا يبدو لي العمل :( القيمة يختفي بعد ko نموذج ملزم بسبب هذا الخط: "viewModel.Title = ko.observable ()"
وأضاف المؤلف Tsar, مصدر
... وإذا كنت تفعل viewModel.Title = ko.observable (viewModel.Title) لتعيين القيمة الأولية ، يطرح knockout.validation.js "Uncaught TypeError"
وأضاف المؤلف Tsar, مصدر

ماذا عن مجرد تسلسل نموذج الصفحة بالكامل إلى json باستخدام JSON.NET أو ما شابه. بعد ذلك ، سيتم ملء صفحتك من خلال روابط عرض الشفرة العادية للمستخدمين غير المتابعين. بعد ذلك ، يمكن أن تكون النصوص البرمجية لصفحتك مثل:

<script>
    ko.applyBindings(@Html.ToJSON(Model));
</script>

أو إذا كان لديك طريقة عرض مكتوبةنموذج

<script>
    var viewModel = new MyViewModel(@Html.ToJSON(Model));
    ko.applyBindings(viewModel);
</script>

من المنطقي أن تكون بنية العميل ونماذج العرض الفعلية متشابهة ، لذا لا يلزم أي تلاعب في شكل json.

تعديل </قوي>

مثال على مساعد toJSON.

public static MvcHtmlString ToJson(this HtmlHelper html, object obj)
{
  JavaScriptSerializer serializer = new JavaScriptSerializer();
  return MvcHtmlString.Create(serializer.Serialize(obj));
}

أتمنى أن يساعدك هذا.

0
وأضاف
من أين جاءت toJSON ()؟ هل أحتاج إلى كتابة هذه الطريقة في نموذج MVC الخاص بي؟
وأضاف المؤلف Tsar, مصدر
ياه آسف كان يجب أن يفسر ذلك كتب هذا على هاتف :) حررت لتعطي سبيل المثال.
وأضاف المؤلف madcapnmckay, مصدر
JasonGoemaat - لا لا أفضل. يجب أن تتعلم عدم الإجابة عن الأسئلة حتى أستطيع تشغيل الكود. في صحتك.
وأضاف المؤلف madcapnmckay, مصدر

لأنني لا أملك سمعة 50 نقطة لإضافة تعليق إلى الإجابة جايسون Goemaat ، قررت إضافة تعليقي هنا كإجابة.

جميع الاعتمادات تذهب إلى جيسون Goemaat.

لم أتمكن من جعل الشفرة تعمل بالنسبة لي. لذلك اضطررت إلى إجراء تغيير بسيط.

        ko.bindingHandlers['myvalue'] = {
    'init': function (element, valueAccessor, allBindingsAccessor) {
        //get initial state of the element            
        var modelValue = valueAccessor();
        var elementValue = ko.selectExtensions.readValue(element);

       //call existing value init code
        ko.bindingHandlers['value'].init(element, valueAccessor, allBindingsAccessor);

        //Save initial state
        modelValue(elementValue);
    },
    'update': function (element, valueAccessor) {
       //call existing value update code
        ko.bindingHandlers['value'].update(element, valueAccessor);
    }
};

لو كان لدي هذا الخط في القمة ،

// call existing value init code
ko.bindingHandlers['value'].init(element, valueAccessor, allBindingsAccessor);

كان يتم حذف الحالة الأصلية للعنصر. مهما كانت القيمة التي أتيحت لي في حقل الإدخال ، كان يتم حذفها.

داخل النموذج لدي هذا:

//publishing comment
self.publishingComment = ko.observable();

ويبدو بلدي MVC مثل هذا

@Html.TextBoxFor(model => model.Comment, new { data_bind = "myvalue: publishingComment" })
0
وأضاف