Knockout.js 剔除映射选项不排除源对象中的其他属性

Knockout.js 剔除映射选项不排除源对象中的其他属性,knockout.js,knockout-mapping-plugin,Knockout.js,Knockout Mapping Plugin,在我的视图模型中,我声明了一个名为“MappeItem”的可观察属性: var MyViewModel = function () { var $scope = this; ... $scope.MappedItem = ko.observable(); ... 我需要映射一个名为“item”的对象,它有几个属性。我只需要在映射的可观察对象中使用其中三个。所以,我想说的是: var mapping = {'include': ["recid", "Prog

在我的视图模型中,我声明了一个名为“MappeItem”的可观察属性:

var MyViewModel = function () {
    var $scope = this;

    ...

    $scope.MappedItem = ko.observable();

    ...
我需要映射一个名为“item”的对象,它有几个属性。我只需要在映射的可观察对象中使用其中三个。所以,我想说的是:

var mapping = {'include': ["recid", "Program", "Station"]};
$scope.MappedItem = ko.mapping.fromJS(item, mapping);
这是可行的,但是我的映射规则被忽略了,我最终得到的“MappedItem”有很多无用的可观察属性

要获取所需内容,我必须在映射选项对象的“忽略”属性中显式声明我不希望映射的每个属性:

var mapping = {
   'ignore': ["AdLength", "Affiliate", ... (MANY OTHER PROPERTIES MORE) ],
   'include': ["recid", "Program", "Station"]
};
$scope.MappedItem = ko.mapping.fromJS(item, mapping);
我尝试过的另一种方法:

ko.mapping.fromJS(item, mapping, $scope.MappedItem);
但这根本不会将任何“item”属性映射到“MappedItem”


我是否应该只使用“包含”来映射所需的属性,而不必在“忽略”选项中显式声明它们?包含

当您将现有视图模型映射回
JS对象时,默认情况下,映射插件仅包括属于
现有视图模型的属性,除非
包含不属于该模型的属性

忽略

当您想
忽略
JS对象的某些属性时
一旦您想让映射插件为您创建视图模型,您可以将它们指定为需要忽略的名称数组

这就是为什么当您创建
视图模型时,映射插件只接受您在
ignore
数组中指定的内容,它实际上拒绝您的
include
,这是有意义的

为了满足您的需求,因为您只想拥有许多属性中的三个,我建议使用这三个可观察变量手动创建子视图模型,这样您的模型上就不会有很多无用的变量

 var MyViewModel = function () {
    var $scope = this;
    ...
    $scope.MappedItem = ko.observableArray();
    $scope.MappedItem($.map(items, function (item) {
         return new ItemViewModel(item);
    })); 
}

var ItemViewModel = function (data) {
    var $scope = this;
    $scope.recid = ko.observableArray(data.recid);
    $scope.Program = ko.observableArray(data.Program);
    $scope.Station = ko.observableArray(data.Station);
}

“include”数组仅在多次映射项时才有用。例如,假设您映射了一个项目。稍后,您将再次映射同一项,但这次,已向该项添加了三个附加属性。默认情况下,Knockout会忽略这三个属性,因为它们第一次不在那里。通过自定义“include”数组,可以强制Knockout映射这三个附加属性

不幸的是,“include”数组不像您预期的那样充当白名单

作为一种解决方法,您可以使用“创建”功能自定义映射对象,并且只包括所需的属性:

Javascript

小提琴:

var item = {
  'recid': '0',
  'Program': 'TestProgram',
  'Station': 'TestStation',
  'ignoredProperty': 'test'
};

var mapping = {
  create: function(options) {
    var orig = options.data;
    var filtered = {
      'recid': ko.observable(orig.recid),
      'Program': ko.observable(orig.Program),
      'Station': ko.observable(orig.Station)
    };
    return filtered;
  }
};

var myViewModel = function() {
  var $scope = this;
  $scope.MappedItem = ko.mapping.fromJS(item, mapping);
};

var vm = new myViewModel();
ko.applyBindings(vm);