Как исключить определенные свойства из Knockoutjs toJS() - программирование
Подтвердить что ты не робот

Как исключить определенные свойства из Knockoutjs toJS()

У меня есть следующая модель:

var model = {
   A: 'One',
   B: 'Two',
   C: 'Three'
};

Я связываю различные элементы интерфейса с этими полями, что отлично работает. Тем не менее, я преобразовываю модель обратно в объект JavaScript, чтобы сохранить любые изменения на сервере:

var goingToServer = ko.toJS(model);

goingToServer будет включать свойства A, B и C. Однако пусть свойство C является огромным куском данных, которые никогда не изменятся. Я бы хотел, чтобы вы не отправили это обратно на сервер.

Есть ли способ сделать toJS() включать только предопределенный набор полей при преобразовании модели обратно в объект JavaScript?

Одна вещь, которую я изучал, - это плагин для нокаута. Он имеет параметр, называемый include, который документирован как таковой:

При преобразовании вашей модели представления обратно в объект JS по умолчанию плагин отображения будет включать только свойства, которые были частью вашего оригинальной модели представления, за исключением того, что она также будет включать Созданное нокаутом свойство _destroy, даже если оно не было частью вашего оригинальный объект. Однако вы можете настроить этот массив:

Однако, похоже, этот плагин не работает так, как описано в документе, поскольку ko.mapping.toJS() будет по-прежнему включать A, B и C, даже если я передаю массив include ['A', 'B']. Я предполагаю, что эта функция предназначена для включения дополнительных полей, которые не были в исходной модели.

Есть ли способ исключить определенные свойства при преобразовании модели обратно в объект JavaScript, если не сделать что-то взломанное, например, создать объект и вручную удалить свойства, которые я не хочу перед отправкой на сервер?

4b9b3361

Ответ 1

Вы пробовали ключевое слово ignore? Он имеет аналогичное использование для include:

var mapping = {
    'ignore': ["propertyToIgnore", "alsoIgnoreThis"]
}
var viewModel = ko.mapping.toJS(data, mapping);

Вы можете просто игнорировать, когда вы выполняете исходное сопоставление данных сервера, тогда он не будет находиться на вашем объекте вообще, когда вы его преобразуете обратно в JS.

Ответ 2

Если у нас есть экземпляр сложной объектной модели в качестве наблюдаемой ссылки vm.Payment как:

{
    "Summary": { 
        "Count": 12,
        "PaymentAmount": 1500,
        "PaymentMethod": "Cheque",
        "PaymentDate": "2015-04-08T22:38:48.552Z",
        "AgentOid": 1208795,
        "AgentName": "Asere Ware"
    }
    //[...]
}

Ответ 3

Хорошо, я выяснил одно решение, которое работает, хотя я надеюсь на лучший подход. Трюк состоит в том, чтобы игнорировать эти поля в плагине сопоставления, а затем добавлять их вручную в качестве вычисленных полей. Вычисляемые поля никогда не окажутся в сгенерированном объекте JavaScript при вызове toJS.

// Utility function to quickly generate a computed field
ko.readonly = function (value)
{
   return ko.computed(function ()
   {
      return value;
   });
};

// View Model
var ViewModel = function (project)
{
   var readonly = ['B', 'C', 'D']; // Fields I want to ignore
   var mapping = {
      'ignore': readonly //Read-only properties, we'll add these manually as computed fields
   };

   // Use Mapping plugin to make everything observable, except the fields above
   ko.mapping.fromJS(project, mapping, this);

   // Now loop through the read only array and add these fields in as computed
   for(var i = 0; i < readonly.length; i++)
   {
      var field = readonly[i];
      this[field] = ko.readonly(project[field]);
   }
}

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

ko.applyBindings(new ViewModel(data));