Я использую плагин отображения нокаута, всегда используя его для создания моей модели просмотра?

Я все еще изучаю правильное использование Knockout, и я обнаружил, что быстро убираюсь от когда-либо набрав ko.observable при настройке моей модели просмотра и вместо этого просто определяя литерал объекта и передавая его через плагин сопоставления с чем-то вроде

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

или, по крайней мере, что-то похожее на то, чтобы наполнить все мои данные атрибутом в представленииModel так

var viewModel = { 
    ... events etc ... , 
    "data": ko.mapping.fromJS(data)
}

Если честно, основной причиной, по которой я это делаю, является необходимость повторного ввода ko.observable и ko.observableArray. Я просто пытаюсь выяснить, является ли это хорошим подходом, и если есть какие-либо недостатки, чтобы скрыть конкретное объявление var x = ko.observable() все вместе. Кроме того, я делаю все это при загрузке, а не в ответ на любой вызов ajax и т.д., Который из того, что я могу сказать, является тем, для которого был создан плагин сопоставления.

В своей работе с нокаутом вы все равно объявляете наблюдаемые вручную, один за другим, или вы ушли с использованием метода mapping.fromJS, который я использую? Существуют ли какие-либо конкретные недостатки для использования плагина отображения так часто, как это?

Edit:

Конкретный пример

В этой статье Стив создает свой режим просмотра, делая

var initialData = [ { ... } , { ... } ]; // json from the serializer
var viewModel = {
    gifts : ko.observableArray(initialData)
};

Обычно я просто использовал ko.mapping.fromJS для этой ситуации, в частности, чтобы убедиться, что объекты в массиве также превращаются в наблюдаемые. Глядя на то, что он сделал, мой подход кажется его излишеством и добавляет немного лишних накладных расходов.

Ответ 1

Мое предложение для вас повторило бы тот же вопрос, на который я только что ответил, fooobar.com/questions/64822/...

Ваше обоснование использования плагина сопоставления является разумным и тем, которое я использую. Зачем вводить больше кода, чем вам нужно?

В моем опыте с нокаутом (все 4 месяца), я обнаружил, что чем меньше я делаю вручную, но и подпрограммы нокаута выполняют свою задачу, тем лучше работают мои приложения. Мое предложение - сначала попробуйте простейший подход. Если это не соответствует вашим потребностям, посмотрите, как простой подход делает это "вещь" и определяет, что должно измениться в соответствии с вашими потребностями.

Ответ 2

После использования Knockout еще немного, я заметил, что в плагине сопоставления есть несколько дополнительных параметров, которые дают вам гораздо более мелкий контроль над процессом сопоставления.

Тип и количество созданных свойств

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

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

Сделать mapping опустить определенные свойства

Вы можете заставить плагин сопоставления полностью исключить свойства из конечного результата, указав такие вещи, как ignore или include. Оба они выполняют одно и то же, прямо противоположным образом.

Примечание. Образцы взяты из документации для плагинов отображения knockout.js, добавленные мной комментарии

Отображение аргумента плагина: include

Следующий фрагмент будет опустить все свойства из исходного объекта, отличного от тех, которые были переданы с помощью аргумента include.

// specify the specific properties to include as observables in the end result 
var mapping = {
    // only include these two properties
    'include': ["propertyToInclude", "alsoIncludeThis"]
}

// viewModel will now only contain the two properties listed above, 
//    and they will be observable
var viewModel = ko.mapping.fromJS(data, mapping);

Отображение аргумента плагина: ignore

Если вы хотите только пропустить определенные свойства из исходного объекта, используйте аргумент ignore, как показано ниже. Он будет делать наблюдаемые из всех свойств исходного объекта, за исключением указанных свойств.

// specify the specific properties to omit from the result, 
//    all others will be made observable
var mapping = {
    // only ignore these two properties
    'ignore': ["propertyToIgnore", "alsoIgnoreThis"]
}

// viewModel will now omit the two properties listed above, 
//    everything else will be included and they will be an observable
var viewModel = ko.mapping.fromJS(data, mapping);

Управлять, какие свойства являются или не выполняются наблюдаемыми

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

Аргумент для сопоставления плагинов: copy

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

// tell the mapping plugin to handle all other properties normally, 
//    but to simply copy this property instead of making it observable
var mapping = {
    'copy': ["propertyToCopy"]
}
var viewModel = ko.mapping.fromJS(data, mapping);

Получить полный контроль над процессом отображения

Если вы хотите иметь 100% -ный контроль над тем, что создано в процессе сопоставления, включая возможность размещения закрытий и подписки в ваших объектах, вы хотите использовать опцию "Создать".

простой результат с вычисленными свойствами

Вот пример, где я сопоставлял данные из вызова ajax объекту с свойством results. Я не хотел ничего наблюдаемого, и мне просто хотелось создать простое сгенерированное свойство, которое было бы сделано из других простых свойств объекта. Возможно, это не самый убедительный пример, но он демонстрирует функциональность.

var searchMappingConfig = {
    // specific configuration for mapping the results property
    "results": {
                    // specific function to use to create the items in the results array
        "create": function (options) {
            // return a new function so we can have the proper scope/value for "this", below
            return new function () {

                // instead of mapping like we normally would: ko.mapping.fromJS(options.data, {}, this);
                // map via extend, this will just copy the properties from the returned json element to "this"
                // we'll do this for a more light weight vm since every last property will just be a plain old property instead of observable
                $.extend(this, options.data);

                // all this to add a vehicle title to each item
                this.vehicleTitle = this.Year + "<br />" + this.Make + " " + this.Model;
                }, this);
            };
        }
    }
}

подписки, закрытие и сопоставление, oh my

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

// here we are specifying the way that items in the make array are created, 
//    since makes has a child array (Models), we will specify the way that 
//    items are created for that as well
var makesModelsMappingConfig = {
   // function that has the configuration for creating makes
   "create": function (options) {
      // return a new function so we can have the proper 
      //    scope/value for "this", below
      return new function () {

         // Note: we have a parent / child relationship here, makes have models. In the 
         //    UI we are selecting makes and then using that to allow the user to select 
         //    models. Because of this, there is going to be some special logic in here 
         //    so that all the child models under a given make, will automatically 
         //    unselect if the user unselects the parent make.

         // make the selected property a private variable so it can be closure'd over
         var makeIsSelected = ko.protectedComputed(false);

         // expose our property so we can bind in the UI
         this.isSelected = makeIsSelected;

         // ... misc other properties and events ...

         // now that we've described/configured how to create the makes, 
         //    describe/configure how to create the models under the makes
         ko.mapping.fromJS(options.data, {
            // specific configuration for the "Models" property                  
            "Models": {
               // function that has the configuration for creating items 
               //    under the Models property
               "create": function (model) {

                  // we'll create the isSelected as a local variable so 
                  //    that we can flip it in the subscription below, 
                  //    otherwise we wouldnt have access to flip it
                  var isSelected = ko.protectedComputed(false);

                  // subscribe to the parents "IsSelected" property so 
                  //    the models can select/unselect themselves
                  parentIsSelected.current.subscribe(function (value) {
                     // set the protected computed to the same 
                     //    value as its parent, note that this 
                     //    is just protected, not the actual value
                     isSelected(value);
                  });


                  // this object literal is what makes up each item 
                  //    in the Models observable array 
                  return {
                     // here we're returning our local variable so 
                     //    we can easily modify it in our subscription
                     "isSelected": isSelected,

                     // ... misc properties to expose 
                     //     under the item in the Model array ...

                  };
               }
            }
         }, this);
      };
   }
};

В целом, я обнаружил, что вам редко нужно 100% объекта, который вы передадите плагину, и вам редко нужно, чтобы 100% его наблюдалось. Вставьте параметры конфигурации сопоставления и создайте всевозможные сложные и простые объекты. Идея состоит в том, чтобы получить все, что вам нужно, ни больше, ни меньше.

Ответ 3

Аллен, мой недавний опыт работы с Knockout.js был похож на ваш. Мы работаем с глубоким иерархическим графиком объекта с сервера, и я определил явные реалистичные функции модели представления, которые сохраняют основную структуру.

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

Это также помогло в создании исходного графика с использованием опции "create" для моделей подвид. В каждом представлении конструктора модели я получаю ссылку на родительскую модель представления плюс данные, с помощью которых можно построить модель детского представления, а затем создавать дополнительные параметры отображения для создания внуков из переданных дочерних данных.

Единственный (слабый) недостаток, который я недавно нашел, как подробно описано в этом вопросе, заключается в том, что при выполнении ko.mapping.toJSON он не подключается ни к одному из JSON переопределения, которые вы, возможно, определили в прототипах ваших моделей просмотра, чтобы исключить свойства из сериализации. Я смог обойти это, указав параметры игнорирования в unmapping, как рекомендовал Райан Нимейер в этом сообщении.

Таким образом, я обязательно буду придерживаться плагина сопоставления. Правила Knockout.js.

Ответ 4

Простым, но полезным дополнением может быть нокаут-данные-прогнозы

В настоящее время он не обрабатывает сопоставления js для viewmodel, но он отлично отображает модель просмотра JS-сопоставлений.