Как использовать knockout.js с ASP.NET MVC ViewModels?

Bounty

Это было некоторое время, и у меня все еще есть пара нерешенных вопросов. Я надеюсь, что добавив награду, возможно, на эти вопросы ответят.

How do you use html helpers with knockout.js

Why was document ready needed to make it work(see first edit for more information)

How do I do something like this if I am using the knockout mapping with my view models? As I do not have a function due to the mapping.

function AppViewModel() {

    // ... leave firstName, lastName, and fullName unchanged here ...

    this.capitalizeLastName = function() {

    var currentVal = this.lastName();        // Read the current value

    this.lastName(currentVal.toUpperCase()); // Write back a modified value

};

I want to use plugins for instance I want to be able to rollback observables as if a user cancels a request I want to be able to go back to the last value. From my research this seems to be achieved by people making plugins like editables

How do I use something like that if I am using mapping? I really don’t want to go to a method where I have in my view manual mapping were I map each MVC viewMode field to a KO model field as I want as little inline javascript as possible and that just seems like double the work and that’s why I like that mapping.

I am concerned that to make this work easy (by using mapping) I will lose a lot of KO power but on the other hand I am concerned that manual mapping will just be a lot of work and will make my views contain too much information and might become in the future harder to maintain(say if I remove a property in the MVC model I have to move it also in the KO viewmodel)

Original Post

Я использую Asp.net MVC 3, и я смотрю в нокаут, как это выглядит довольно круто, но мне трудно понять, как он работает с Asp.net MVC, особенно посмотреть модели.

Для меня сейчас я делаю что-то вроде этого

 public class CourseVM
    {
        public int CourseId { get; set; }
        [Required(ErrorMessage = "Course name is required")]
        [StringLength(40, ErrorMessage = "Course name cannot be this long.")]
        public string CourseName{ get; set; }


        public List<StudentVm> StudentViewModels { get; set; }

}

Я хотел бы иметь Vm, который имеет некоторые основные свойства, такие как CourseName, и поверх него будет простая проверка. Модель Vm может содержать и другие модели представлений, если это необходимо.

Затем я передал бы этот Vm в представление, где бы я использовал помощники HTML, чтобы помочь мне показать его пользователю.

@Html.TextBoxFor(x => x.CourseName)

У меня могут быть какие-то циклы foreach или что-то еще, чтобы вытащить данные из коллекции моделей просмотра учеников.

Затем, когда я отправлю форму, я буду использовать jquery иserialize array и отправьте его в метод действия контроллера, который связал бы его с моделью представления.

С knockout.js все по-другому, так как теперь у вас есть для него модели представления, и из всех примеров, которые я видел, они не используют помощников html.

Как вы используете эти 2 функции MVC с knockout.js?

я нашел это видео и вкратце (последние несколько минут видео @ 18:48) идет речь о том, как использовать view-модели, в основном имея встроенный скрипт, который имеет view-модель knockout.js, которой присваиваются значения в ViewModel.

Это единственный способ сделать это? Как насчет моего примера с коллекцией моделей в нем? Должен ли я иметь цикл foreach или что-то еще, чтобы извлечь все значения и назначить их в нокаут?

Что касается помощников HTML, видео ничего не говорит о них.

Это две области, которые сбивают меня с толку, поскольку не многие люди, кажется, говорят об этом, и это оставляет меня в замешательстве из-за того, как исходные значения и все остальное попадает в поле зрения, когда пример - это просто какой-то жестко заданный пример значения.

Edit

Я пробую то, что предложил Дарин Димитров, и это, кажется, работает (хотя мне пришлось внести некоторые изменения в его код). Не уверен, почему я должен был использовать готовый документ, но почему-то все было не готово без него.

@model MvcApplication1.Models.Test

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <title>Index</title>
    <script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
    <script src="../../Scripts/knockout-2.1.0.js" type="text/javascript"></script>
    <script src="../../Scripts/knockout.mapping-latest.js" type="text/javascript"></script>
   <script type="text/javascript">

   $(function()
   {
      var model = @Html.Raw(Json.Encode(Model));


// Activates knockout.js
ko.applyBindings(model);
   });

</script>

</head>
<body>
    <div>
        <p>First name: <strong data-bind="text: FirstName"></strong></p>
        <p>Last name: <strong data-bind="text: LastName"></strong></p>
        @Model.FirstName , @Model.LastName
    </div>
</body>
</html>

Я должен был обернуть его вокруг документа jquery, готового заставить его работать.

Я также получил это предупреждение. Не уверен, что это все.

Warning 1   Conditional compilation is turned off   -> @Html.Raw

Так что у меня есть отправная точка, я думаю, что, по крайней мере, я обновлюсь, когда закончу играть, и как это работает.

Я пытаюсь пройти через интерактивные учебники, но вместо этого использую ViewModel.

Не уверен, как решать эти части еще

function AppViewModel() {
    this.firstName = ko.observable("Bert");
    this.lastName = ko.observable("Bertington");
}

или же

function AppViewModel() {
    // ... leave firstName, lastName, and fullName unchanged here ...

    this.capitalizeLastName = function() {
        var currentVal = this.lastName();        // Read the current value
        this.lastName(currentVal.toUpperCase()); // Write back a modified value
    };

Edit 2

Я смог разобраться с первой проблемой. Понятия не имею по поводу второй проблемы. Тем не менее, хотя. У кого-нибудь есть идеи?

 @model MvcApplication1.Models.Test

    @{
        Layout = null;
    }

    <!DOCTYPE html>

    <html>
    <head>
        <title>Index</title>
        <script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
        <script src="../../Scripts/knockout-2.1.0.js" type="text/javascript"></script>
        <script src="../../Scripts/knockout.mapping-latest.js" type="text/javascript"></script>
       <script type="text/javascript">

       $(function()
       {
        var model = @Html.Raw(Json.Encode(Model));
        var viewModel = ko.mapping.fromJS(model);
        ko.applyBindings(viewModel);

       });

    </script>

    </head>
    <body>
        <div>
            @*grab values from the view model directly*@
            <p>First name: <strong data-bind="text: FirstName"></strong></p>
            <p>Last name: <strong data-bind="text: LastName"></strong></p>

            @*grab values from my second view model that I made*@
            <p>SomeOtherValue <strong data-bind="text: Test2.SomeOtherValue"></strong></p>
            <p>Another <strong data-bind="text: Test2.Another"></strong></p>

            @*allow changes to all the values that should be then sync the above values.*@
            <p>First name: <input data-bind="value: FirstName" /></p>
            <p>Last name: <input data-bind="value: LastName" /></p>
            <p>SomeOtherValue <input data-bind="value: Test2.SomeOtherValue" /></p>
            <p>Another <input data-bind="value: Test2.Another" /></p>

           @* seeing if I can do it with p tags and see if they all update.*@
            <p data-bind="foreach: Test3">
                <strong data-bind="text: Test3Value"></strong> 
            </p>

     @*took my 3rd view model that is in a collection and output all values as a textbox*@       
    <table>
        <thead><tr>
            <th>Test3</th>
        </tr></thead>
          <tbody data-bind="foreach: Test3">
            <tr>
                <td>    
                    <strong data-bind="text: Test3Value"></strong> 
<input type="text" data-bind="value: Test3Value"/>
                </td>
            </tr>    
        </tbody>
    </table>

контроллер

  public ActionResult Index()
    {
              Test2 test2 = new Test2
        {
            Another = "test",
            SomeOtherValue = "test2"
        };

        Test vm = new Test
        {
            FirstName = "Bob",
            LastName = "N/A",
             Test2 = test2,

        };
        for (int i = 0; i < 10; i++)
        {
            Test3 test3 = new Test3
            {
                Test3Value = i.ToString()
            };

             vm.Test3.Add(test3);
        }

        return View(vm);
    }
 beyond-code09 дек. 2012 г., 21:25
Я только что написал сообщение в блоге, чтобы ответить на другой подобный вопрос:roysvork.wordpress.com/2012/12/09/… Это может не ответить на ваш вопрос полностью, но дает вам хорошее представление о том, как все может работать. Надеюсь, что в следующем посте я расскажу об этом. Не стесняйтесь задавать мне любые вопросы в комментариях к сообщению или здесь, если вам нужна дополнительная информация.

Ответы на вопрос(3)

Вы можете сериализовать модель представления ASP.NET MVC в переменную javascript:

@model CourseVM
<script type="text/javascript">
    var model = @Html.Raw(Json.Encode(Model));
    // go ahead and use the model javascript variable to bind with ko
</script>

Есть много примеров внокаут-документация что вы могли бы пройти.

 15 июн. 2012 г., 19:35
Это нормально, что вы не видите ничего общего с asp.net mvc. Knockout - это фреймворк на стороне клиента. Он не знает и не заботится о том, какой язык на стороне сервера вы используете. Эти 2 основы должны быть абсолютно отделены.
 15 июн. 2012 г., 23:07
@ chobo2, нокаут - это фреймворк на стороне клиента. Он использует модели представления на клиенте для реализации шаблона MVC на клиенте. Сервер развязан. Вы также можете использовать модели просмотра на нем. Это просто 2 разных места. Если у вас есть какая-то сложная логика, которую вы хотите реализовать на клиенте с помощью javascript, то нокаут может упростить это. В противном случае, честно говоря, вам это не нужно.
 15 июн. 2012 г., 19:33
Какую проблему вы пытаетесь решить? Если вы хотите посмотреть MVC и довольны тем, как их использовать, вы можете придерживаться этого. Если вы хотите связать данные на стороне клиента и манипулировать ими, то KO - отличный выбор. Вы можете сгенерировать свою KO viewmodel из своего кода MVC, как показывает этот ответ. Он берет VM и сериализует его в JSON. Затем на клиенте вы можете сопоставить результаты с моделью представления javascript. Затем привяжите viewmodel к представлению, и все готово. Ключ в том, что MVC и KO не должны быть связаны каким-либо образом, если только вы не хотите, чтобы они были. Все зависит от проблемы, которую вы пытаетесь решить.
 chobo215 июн. 2012 г., 19:26
Да, я просмотрел интерактивное руководство, которое есть на сайте, но я действительно никогда не вижу ничего общего с asp.net mvc. Я вижу, что у них также есть некоторый плагин сопоставления, но я не уверен, как он вписывается. В вашем примере, как бы вы связали его с моделью выбивки (в другом скрипте). Я действительно хочу иметь как можно меньше встроенного javascript (не предпочтительнее, но я думаю, что это невозможно)
 chobo215 июн. 2012 г., 21:46
@JohnPapa - мне нравится, как я делаю вещи сейчас, но мне также нравится изучать новые вещи (я вижу, что КО может быть очень полезным в некоторых ситуациях). Я знаю, что KO - это сценарий на стороне клиента, но мне кажется, что они работают вместе. В настоящее время я генерирую свои представления с использованием моделей представления и HTML-помощников. Так что, на мой взгляд, нокаут должен работать вместе с этим. Например, скажем, у вас есть диалог редактирования. Как бы вы спроектировали и заполнили значения из БД в эти поля. Если бы я использовал свой путь, это было бы представление помощников HTML, который имеет viewModel. Заполнит viewmodel и отправит его через метод действия и использует его.

Чтобы получить дополнительные вычисляемые свойства после сопоставления сервера, вам необходимо дополнительно улучшить ваши модели представления на стороне клиента.

Например:

var viewModel = ko.mapping.fromJS(model);

viewModel.capitalizedName = ko.computed(function() {...}, viewModel);

Поэтому каждый раз, когда вы отображаете из необработанного JSON, вам нужно будет повторно применять вычисленные свойства.

Кроме того, подключаемый модуль предоставляет возможность постепенно обновлять модель представления, а не воссоздавать ее каждый раз, когда вы переходите назад и вперед (используйте дополнительный параметр вfromJS):

// Every time data is received from the server:
ko.mapping.fromJS(data, viewModel);

И это выполняет постепенное обновление данных в вашей модели только сопоставленных свойств. Вы можете прочитать больше об этом вкартографическая документация

Вы упомянули в комментариях к ответу ДаринаFluentJSON пакет. Я автор этого, но его вариант использования более конкретен, чем ko.mapping. Как правило, я бы использовал его только в том случае, если ваши view-модели являются односторонними (т. Е. Сервер -> клиент), а затем данные отправляются обратно в каком-то другом формате (или не отправляются вообще). Или, если ваша модель представления javascript должна быть в существенно отличном формате от вашей модели сервера.

 05 июл. 2012 г., 21:42
Я не использовал ни один из плагинов, так что не уверен. То, что я делал в прошлом, было просто подписаться на каждое изменение и сохранить стек сериализованных состояний viewmodel, которые я бы подтолкнул к изменению и выдвинул отмену (see this question).
 05 июл. 2012 г., 21:42
Отображение не удерживает вас от какой-либо функциональности, вам просто нужно убедиться и соблюдать его соглашения о том, как он обрабатывает сопоставление с JS и чтобы все это хорошо сочеталось.
 chobo205 июл. 2012 г., 21:30
Хм, тогда я думаю, что, возможно, FluentJSON не для меня, так как мои модели представления большую часть времени идут в обе стороны (я обычно отправляю его обратно через json, а затем связываю его с моделью представления в параметре метода действия). Знаете ли вы, как я могу использовать те плагины, которые я упоминал, как редактируемые? Наконец, я теряю какую-либо функциональность, используя сопоставление и пытаясь использовать мою модель представления, а не использовать ее?
 05 июл. 2012 г., 22:48
Ах да, извините, я говорил о своем ответе на этот вопрос, извините, должен был связаться напрямую.
 chobo205 июл. 2012 г., 21:51
Хорошо принятый ответ на вопрос, который вы разместили, в основном, что плагин будет. Это то, что смущает меня, так как вы можете видеть, что они создают модель представления, а затем используют свою функцию (ko.observableArrayWithUndo ([])). Если я занимаюсь картированием, я не знаю, как это сделать. Единственное, что приходит на ум, - это написать свое собственное отображение (что, я сомневаюсь, я мог бы исправить в это время), которое отменяет наблюдаемое, или отобразить каждое свойство, но тогда у меня в основном есть дубликаты моделей представления, одна для серверной части и одна для клиента, и я страшно, что станет неуправляемым
Решение Вопроса

Я думаю, что я суммировал все ваши вопросы, если я что-то пропустил, пожалуйста, дайте мне знать (If you could summarize up all your questions in one place would be nice =))

Note. Compatibility with the ko.editable plug-in added

Download the full code How do you use html helpers with knockout.js

Это просто:

@Html.TextBoxFor(model => model.CourseId, new { data_bind = "value: CourseId" })

Куда:

value: CourseId indicates that you are binding the value property of the input control with the CourseId property from your model and your script model

Результат:

<input data-bind="value: CourseId" data-val="true" data-val-number="The field CourseId must be a number." data-val-required="The CourseId field is required." id="CourseId" name="CourseId" type="text" value="12" />
Why was document ready needed to make it work(see first edit for more information)

Я еще не понимаю, почему вам нужно использоватьready событие для сериализации модели, но кажется, что это простоrequired (Не беспокойтесь об этом, хотя)

How do I do something like this if I am using the knockout mapping with my view models? As I do not have a function due to the mapping.

Если я правильно понимаю, вам нужно добавить новый метод в модель KO, хорошо, что это модели с простым слиянием

Для получения дополнительной информации, в разделе -Картинг из разных источников-

function viewModel() {
    this.addStudent = function () {
        alert("de");
    };
};

$(function () {
    var jsonModel = '@Html.Raw(JsonConvert.SerializeObject(this.Model))';
    var mvcModel = ko.mapping.fromJSON(jsonModel);

    var myViewModel = new viewModel();
    var g = ko.mapping.fromJS(myViewModel, mvcModel);

    ko.applyBindings(g);
});
About the warning you were receiveing

Warning 1 Conditional compilation is turned off -> @Html.Raw

Вам нужно использовать цитаты

Compatibility with the ko.editable plug-in

Я думал, что это будет более сложно, но оказывается, что интеграция действительно проста, чтобы сделать вашу модель редактируемой, просто добавьте следующую строку: (помните, что в этом случае я использую смешанную модель с сервера и добавление расширения в клиенте и редактирование просто работает ... это здорово):

    ko.editable(g);
    ko.applyBindings(g);

Отсюда вам просто нужноplay например, с вашими привязками, используя расширения, добавленные плагином, у меня есть кнопка, чтобы начать редактировать мои поля, как это, и на этой кнопке я запускаю процесс редактирования:

    this.editMode = function () {
        this.isInEditMode(!this.isInEditMode());
        this.beginEdit();
    };

Затем у меня есть кнопки подтверждения и отмены со следующим кодом:

    this.executeCommit = function () {
        this.commit();
        this.isInEditMode(false);
    };
    this.executeRollback = function () {
        if (this.hasChanges()) {
            if (confirm("Are you sure you want to discard the changes?")) {
                this.rollback();
                this.isInEditMode(false);
            }
        }
        else {
            this.rollback();
            this.isInEditMode(false);
        }
    };

И, наконец, у меня есть одно поле, чтобы указать, находятся ли поля в режиме редактирования или нет, это просто для привязки свойства enable.

this.isInEditMode = ko.observable(false);
About your array question

I might have some foreach loops or something to get the data out of the collection of Student View Models.

Then when I would submit the form I would use jquery and serialize array and send it to a controller action method that would bind it back to the viewmodel.

Вы можете сделать то же самое с KO, в следующем примере я создам следующий вывод:

enter image description here

В основном здесь у вас есть два списка, созданные с использованиемHelpers и связаны с нокаутом, у них естьdblClick Привязка к событию: при запуске удалите выбранный элемент из текущего списка и добавьте его в другой список при публикации вControllerсодержимое каждого списка отправляется в виде данных JSON и повторно присоединяется к модели сервера

Nuggets:

Newtonsoft jQuery knockoutjs Knockout.Mapping

внешнийскрипты.

Controller code
    [HttpGet]
    public ActionResult Index()
    {
        var m = new CourseVM { CourseId = 12, CourseName = ".Net" };

        m.StudentViewModels.Add(new StudentVm { ID = 545, Name = "Name from server", Lastname = "last name from server" });

        return View(m);
    }

    [HttpPost]
    public ActionResult Index(CourseVM model)
    {
        if (!string.IsNullOrWhiteSpace(model.StudentsSerialized))
        {
            model.StudentViewModels = JsonConvert.DeserializeObject<List<StudentVm>>(model.StudentsSerialized);
            model.StudentsSerialized = string.Empty;
        }

        if (!string.IsNullOrWhiteSpace(model.SelectedStudentsSerialized))
        {
            model.SelectedStudents = JsonConvert.DeserializeObject<List<StudentVm>>(model.SelectedStudentsSerialized);
            model.SelectedStudentsSerialized = string.Empty;
        }

        return View(model);
    }
Model
public class CourseVM
{
    public CourseVM()
    {
        this.StudentViewModels = new List<StudentVm>();
        this.SelectedStudents = new List<StudentVm>();
    }

    public int CourseId { get; set; }

    [Required(ErrorMessage = "Course name is required")]
    [StringLength(100, ErrorMessage = "Course name cannot be this long.")]
    public string CourseName { get; set; }

    public List<StudentVm> StudentViewModels { get; set; }
    public List<StudentVm> SelectedStudents { get; set; }

    public string StudentsSerialized { get; set; }
    public string SelectedStudentsSerialized { get; set; }
}

public class StudentVm
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Lastname { get; set; }
}
CSHTML page
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>CourseVM</legend>

        <div>
            <div class="editor-label">
                @Html.LabelFor(model => model.CourseId)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(model => model.CourseId, new { data_bind = "enable: isInEditMode, value: CourseId" })
                @Html.ValidationMessageFor(model => model.CourseId)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.CourseName)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(model => model.CourseName, new { data_bind = "enable: isInEditMode, value: CourseName" })
                @Html.ValidationMessageFor(model => model.CourseName)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.StudentViewModels);
            </div>
            <div class="editor-field">

                @Html.ListBoxFor(
                    model => model.StudentViewModels,
                    new SelectList(this.Model.StudentViewModels, "ID", "Name"),
                    new
                    {
                        style = "width: 37%;",
                        data_bind = "enable: isInEditMode, options: StudentViewModels, optionsText: 'Name', value: leftStudentSelected, event: { dblclick: moveFromLeftToRight }"
                    }
                )
                @Html.ListBoxFor(
                    model => model.SelectedStudents,
                    new SelectList(this.Model.SelectedStudents, "ID", "Name"),
                    new
                    {
                        style = "width: 37%;",
                        data_bind = "enable: isInEditMode, options: SelectedStudents, optionsText: 'Name', value: rightStudentSelected, event: { dblclick: moveFromRightToLeft }"
                    }
                )
            </div>

            @Html.HiddenFor(model => model.CourseId, new { data_bind="value: CourseId" })
            @Html.HiddenFor(model => model.CourseName, new { data_bind="value: CourseName" })
            @Html.HiddenFor(model => model.StudentsSerialized, new { data_bind = "value: StudentsSerialized" })
            @Html.HiddenFor(model => model.SelectedStudentsSerialized, new { data_bind = "value: SelectedStudentsSerialized" })
        </div>

        <p>
            <input type="submit" value="Save" data-bind="enable: !isInEditMode()" /> 
            <button data-bind="enable: !isInEditMode(), click: editMode">Edit mode</button><br />
            <div>
                <button data-bind="enable: isInEditMode, click: addStudent">Add Student</button>
                <button data-bind="enable: hasChanges, click: executeCommit">Commit</button>
                <button data-bind="enable: isInEditMode, click: executeRollback">Cancel</button>
            </div>
        </p>
    </fieldset>
}
Scripts
<script src="@Url.Content("~/Scripts/jquery-1.7.2.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/knockout-2.1.0.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/knockout.mapping-latest.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/ko.editables.js")" type="text/javascript"></script>

<script type="text/javascript">
    var g = null;
    function ViewModel() {
        this.addStudent = function () {
            this.StudentViewModels.push(new Student(25, "my name" + new Date(), "my last name"));
            this.serializeLists();
        };
        this.serializeLists = function () {
            this.StudentsSerialized(ko.toJSON(this.StudentViewModels));
            this.SelectedStudentsSerialized(ko.toJSON(this.SelectedStudents));
        };
        this.leftStudentSelected = ko.observable();
        this.rightStudentSelected = ko.observable();
        this.moveFromLeftToRight = function () {
            this.SelectedStudents.push(this.leftStudentSelected());
            this.StudentViewModels.remove(this.leftStudentSelected());
            this.serializeLists();
        };
        this.moveFromRightToLeft = function () {
            this.StudentViewModels.push(this.rightStudentSelected());
            this.SelectedStudents.remove(this.rightStudentSelected());
            this.serializeLists();
        };
        this.isInEditMode = ko.observable(false);
        this.executeCommit = function () {
            this.commit();
            this.isInEditMode(false);
        };
        this.executeRollback = function () {
            if (this.hasChanges()) {
                if (confirm("Are you sure you want to discard the changes?")) {
                    this.rollback();
                    this.isInEditMode(false);
                }
            }
            else {
                this.rollback();
                this.isInEditMode(false);
            }
        };
        this.editMode = function () {
            this.isInEditMode(!this.isInEditMode());
            this.beginEdit();
        };
    }

    function Student(id, name, lastName) {
        this.ID = id;
        this.Name = name;
        this.LastName = lastName;
    }

    $(function () {
        var jsonModel = '@Html.Raw(JsonConvert.SerializeObject(this.Model))';
        var mvcModel = ko.mapping.fromJSON(jsonModel);

        var myViewModel = new ViewModel();
        g = ko.mapping.fromJS(myViewModel, mvcModel);

        g.StudentsSerialized(ko.toJSON(g.StudentViewModels));
        g.SelectedStudentsSerialized(ko.toJSON(g.SelectedStudents));

        ko.editable(g);
        ko.applyBindings(g);
    });
</script>

Примечание: я только что добавил эти строки:

        @Html.HiddenFor(model => model.CourseId, new { data_bind="value: CourseId" })
        @Html.HiddenFor(model => model.CourseName, new { data_bind="value: CourseName" })

Потому что, когда я отправляю форму, мои поля отключены, поэтому значения не передаются на сервер, поэтому я добавил пару скрытых полей, чтобы сделать трюк

 chobo209 июл. 2012 г., 18:04
Я проверю это, когда смогу. Многое пришлось изменить, чтобы заставить его работать? Мне интересно, если для каждого плагина я найду, придется ли мне вносить изменения в него, а затем сохранять свою версию.
 09 июл. 2012 г., 12:40
Я просто добавил совместимость сko.editables плагин, вы можете проверить обновленный ответ или, если вы хотите, вы можете скачать весь проект, чтобы запустить его локально
 20 сент. 2012 г., 05:18
Спасибо большое, я узнал несколько новых стратегий из твоего ответа. Престижность!
 09 июл. 2012 г., 20:17
Нету. Вы будете удивлены, это почти из коробки
 chobo209 июл. 2012 г., 07:22
Хм, очень информативно. Из вашего ответа и ответа Pual я думаю, что я почти получил ответы на все мои вопросы, за исключением того, как использовать плагины, такие как редактируемые. Надеюсь, кто-то знает, как я могу это использовать.

Ваш ответ на вопрос