Як користуватися knockout.js з ASP.NET MVC ViewModels?


129

Баунті

Минуло деякий час, і у мене ще є пара невирішених питань. Я сподіваюся, що додавши щедроту, можливо, на ці запитання отримають відповіді.

  1. Як ви користуєтеся html-помічниками з knockout.js
  2. Чому для його роботи був необхідний документ (див. Першу редакцію для отримання додаткової інформації)

  3. Як я можу зробити щось подібне, якщо я використовую нокаут-карти зі своїми моделями перегляду? Оскільки у мене немає функції через картографування.

    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
    
    };
  4. Наприклад, я хочу використовувати плагіни, я хочу мати можливість відкатати спостережувані дані, як якщо користувач скасовує запит, я хочу мати можливість повернутися до останнього значення. З мого дослідження, схоже, цього досягають люди, які роблять плагіни як редаговані

    Як я можу використовувати щось подібне, якщо використовую картографування? Я дійсно не хочу переходити до методу, коли в моєму огляді маю ручне картографування: я позначаю кожне поле MVC viewMode на поле моделі KO, оскільки я хочу якомога менше вбудованого JavaScript, і це просто схоже на подвійну роботу, і це чому мені подобається таке картографування.

  5. Я стурбований тим, що щоб зробити цю роботу легкою (за допомогою картографування), я втрачу багато сил КО, але, з іншого боку, я переживаю, що ручне картографування буде просто багато роботи і змусить мої погляди містити занадто багато інформації та в майбутньому може стати важче підтримувати (скажімо, якщо я видаляю властивість у моделі MVC, я повинен перемістити її також у переглядовій моделі KO)


Оригінальна публікація

Я використовую 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 може містити в ній і інші моделі перегляду, а також за потреби.

Потім я передавав би цей ВМ на Перегляд, якби я використовував html-помічники, щоб допомогти мені відобразити його користувачеві.

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

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

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

З knockout.js все по-іншому, тому що ви тепер отримали для цього перегляд моделей, і з усіх прикладів я бачив, що вони не використовують html-помічників.

Як ви використовуєте ці 2 функції MVC з knockout.js?

Я знайшов це відео, і воно коротко (останні кілька хвилин відео @ 18:48) переходить до способу використання viewmodels, в основному має вбудований сценарій, який має viewmodel knockout.js, який отримує присвоєні значення у ViewModel.

Це єдиний спосіб зробити це? Як щодо мого прикладу з колекцією моделей перегляду? Чи повинен я мати цикл foreach чи щось, щоб витягнути всі значення та призначити його нокаутом?

Щодо html-помічників, відео про них нічого не говорить.

Це дві сфери, які збивають з пантелику мою людину, бо не так багато людей, здається, говорять про це, і це залишає мене збентеженим тим, як початкові значення і все стає на думку, коли колись приклад - це лише якийсь жорсткий приклад цінності.


Редагувати

Я пробую те, що запропонував Дарин Димитров, і це, здається, спрацювало (мені довелося внести деякі зміни в його код). Не впевнений, чому мені довелося використовувати готовий документ, але якось все не було готове без нього.

@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
    };


Редагувати 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);
    }

2
Я щойно написав повідомлення в блозі, щоб відповісти на інше подібне запитання: roysvork.wordpress.com/2012/12/09/… Він може не відповісти на ваше запитання повністю, але він дає вам гарне уявлення про те, як все може працювати. Я сподіваюсь продовжити цю роботу з подальшою посадою у не надто віддаленому майбутньому. Не соромтеся задавати мені будь-які запитання в коментарях до посту чи тут, якщо вам потрібна додаткова інформація.
поза кодом

Відповіді:


180

Я думаю, що я узагальнив усі ваші запитання, якщо я щось пропустив, будь ласка, повідомте мене ( Якщо ви зможете підсумувати всі свої запитання в одному місці, було б добре =))

Примітка. Сумісність із ko.editableдодаванням плагіну

Завантажте повний код

Як ви користуєтеся html-помічниками з knockout.js

Це легко:

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

Де:

  • value: CourseIdвказує на те, що ви прив'язуєте valueвластивістьinput керування CourseIdвластивістю своєї моделі та вашої моделі сценарію

Результат:

<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" />

Чому для його роботи був необхідний документ (див. Першу редакцію для отримання додаткової інформації)

Я ще не розумію, для чого потрібно використовувати readyподію для серіалізації моделі, але здається, що це просто потрібно (Хоч про це не турбуватися)

Як я можу зробити щось подібне, якщо я використовую нокаут-карти зі своїми моделями перегляду? Оскільки у мене немає функції через картографування.

Якщо я правильно розумію, вам потрібно додати новий метод до моделі 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);
});

Про попередження, яке ви отримували

Попередження 1 Умовна компіляція вимкнена -> @ Html.Raw

Потрібно використовувати лапки

Сумісність із плагіном ko.editable

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

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

Звідси вам просто потрібно пограти зі своїми прив’язками, використовуючи розширення, додані плагіном, наприклад, у мене є кнопка, щоб почати редагувати мої поля так, і в цій кнопці я запускаю процес редагування:

    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);

Про ваше питання про масив

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

Тоді, коли я надсилаю форму, я б використовував jquery і серіалізував масив і надсилав його до методу дій контролера, який би прив'язував його до перегляду.

Ви можете зробити те ж саме з KO, у наступному прикладі я створити наступний вихід:

введіть тут опис зображення

В основному тут у вас є два списки, створені за допомогою Helpersі пов'язаних з KO, вони маютьdblClick події прив'язують до того, що при запуску видаліть вибраний елемент із поточного списку та додайте його до іншого списку, коли ви публікуєте Controllerвміст кожного список надсилається у вигляді даних JSON і повторно додається до моделі сервера

Самородки:

Зовнішні сценарії .

Код контролера

    [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);
    }

Модель

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

@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>
}

Сценарії

<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" })

Тому що, коли я надсилаю форму, мої поля вимкнено, тому значення не передаються серверу, тому я додав пару прихованих полів, щоб зробити трюк


Хм, дуже інформативний. З вашої відповіді та відповіді Pual, я думаю, що я майже отримав відповіді на всі мої запитання, за винятком того, як використовувати плагіни, як редаговані. Сподіваємось, хтось знає, як я можу це використати.
chobo2

1
Я щойно додав сумісність із ko.editablesплагіном, ви можете перевірити оновлений відгук або, якщо хочете, можете завантажити весь проект, щоб запустити його локально
Jupaol

Я перевірю це, коли зможу. Чи потрібно було багато чого змінити, щоб змусити його працювати? Мені цікаво, чи для кожного плагіна я виявляю, чи мені доведеться його змінити, а потім доведеться зберігати свою власну версію.
chobo2

Ні. Ви будете здивовані, це майже нестандартно
Джупаол

1
Спасибі людині, я дізнався кілька нових стратегій з вашої відповіді. Кудо!
sky-dev

23

Ви можете серіалізувати модель перегляду 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>

У документації по нокауту є багато прикладів, які ви могли пройти.


1
Так, я пройшов інтерактивний підручник, який вони мають на сайті, але я дійсно ніколи не бачу нічого спільного з asp.net mvc. Я бачу, що у них також є якийсь плагін для відображення, але не впевнений, як це підходить. У вашому прикладі, як би ви прив'язали його до нокаут-моделі (в іншому сценарії). Я дуже хочу мати якомога менше вбудованого JavaScript (не бажано, але, мабуть, це не можливо)
chobo2

2
Яку проблему ви намагаєтеся вирішити? Якщо ви хочете переглядати MVC і задоволені тим, як ними користуватися, можете там дотримуватися. Якщо ви хочете прив'язувати та керувати даними на стороні клієнта, то КО - чудовий вибір. Ви можете згенерувати модель перегляду KO з коду MVC, як показує ця відповідь. Він приймає vm і серіалізує його до json. Потім на клієнті ви зможете відобразити результати на перегляд JavaScript. Потім прив’яжіть модуль перегляду до перегляду, і ви все налаштовані. Ключовим моментом є те, що MVC та KO не повинні бути пов'язані будь-яким способом, якщо ви не хочете, щоб вони були. Все залежить від проблеми, яку ви намагаєтеся вирішити.
Джон Папа

1
Це нормально, що ви не бачите нічого спільного з asp.net mvc. Нокаут - це рамка на стороні клієнта. Він не знає і не піклується, якою мовою на стороні сервера ви користуєтесь. Ці 2 рамки повинні бути абсолютно відокремленими.
Дарин Димитров

@JohnPapa - Мені подобається, як я зараз роблю речі, але мені також подобається вчитися новим (я бачу, що КО може бути дуже корисним у деяких ситуаціях). Я знаю, що КО - це клієнтський сценарій, але я вважаю, що вони працюють разом. Наразі генерую свої погляди за допомогою моделей перегляду та html-помічників. Отже, на мій погляд, КО потрібно працювати разом з цим. Наприклад, скажіть, у вас діалогове вікно редагування. Як би ви спроектували та заповнили значення з db у ці поля. Якби я використовував свій шлях, це був би вид помічників html, який має viewModel. Поповнить переглядний модуль і надішле його методом дії та використає його.
chobo2

1
@ chobo2, нокаут - це структура на стороні клієнта. Він використовує моделі перегляду на клієнті для реалізації схеми MVC на клієнті. Сервер роз'єднаний. На ньому також можна використовувати переглядати моделі. Це просто 2 різних місця. Якщо у вас є якась складна логіка, яку ви хочете реалізувати на клієнті за допомогою javascript, то нокаут може спростити це. Інакше, чесно кажучи, вам це не потрібно.
Дарин Димитров

2

Для досягнення додаткових обчислюваних властивостей після відображення сервера вам потрібно буде додатково покращити свої моделі перегляду на стороні клієнта.

Наприклад:

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. Я, як правило, використовую його лише в тому випадку, якщо ваші переглядачі є односторонніми (наприклад, сервер -> клієнт), а потім дані розміщуються назад у якомусь іншому форматі (або взагалі немає). Або якщо ваша модель перегляду JavaScript повинна мати суттєво інший формат від вашої моделі сервера.


Хм, то, мабуть, FluentJSON не для мене, тому що мої viewmodels більшість часу йдуть обома способами (зазвичай я надсилаю його назад, хоча через json, а потім прив'язую його до viewmodel у параметрі методу дії). Чи знаєте ви, як я міг використовувати ті плагіни, які я згадав, як редаговані? Нарешті, я втрачаю будь-яку функціональність, використовуючи картографування та намагаючись використовувати свій viewmodel vs не використовуючи його?
chobo2

Я не використовував жоден із плагінів, так що не впевнений. Що я робив у минулому, це просто підписатись на кожну зміну та зберегти стопку серіалізованого режиму перегляду, який я б підштовхнув до змін та перейшов до скасування ( див. Це питання ).
Пол Тайнг

картографування не утримує вас від будь-якої функціональності, вам просто потрібно переконатися в цьому і дотримуватися його домовленостей щодо того, як воно обробляє картографування до та від JS, щоб все це грало добре разом.
Пол Тайнг

Добре прийнята відповідь на поставлене вами питання - це в основному плагін. Це те, що мене бентежить, як ви бачите, що вони роблять viewmodel, а потім використовують функцію, яку вони зробили (ko.observableArrayWithUndo ([])). Якщо я займаюся картографуванням, я не знаю, як це зробити. Єдине, що спадає на думку, це написати власне картографування (те, що я сумніваюся, що я міг би зробити це право), яке має скасувати спостереження або перенести на карту кожну властивість, але тоді я, як правило, маю дублюючу модель перегляду - одну для сервера та одну для клієнта, і я боїться, що стане
неможливим

Ага так вибачте, що я говорив про свою відповідь на це питання, вибачте, мав би зв’язатися безпосередньо.
Пол Тайнг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.