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

时间:2016-10-05 18:50:06

标签: knockout.js knockout-mapping-plugin

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

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

    ...

    $scope.MappedItem = ko.observable();

    ...

我需要映射一个名为'item'的对象,它有几个属性。我在映射的observable中只需要其中的三个。所以,这就是我正在尝试的事情:

var mapping = {'include': ["recid", "Program", "Station"]};
$scope.MappedItem = ko.mapping.fromJS(item, mapping);

这有效但我的映射规则被忽略了,我最终得到的'MappedItem'有很多无用的可观察属性。

为了获得我想要的东西,我必须在映射选项对象的'ignore'属性中显式声明我不希望映射的每个属性:

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'。

我不应该只使用'include'来映射所需的属性,而不必在'ignore'选项中明确声明它们吗?

2 个答案:

答案 0 :(得分:1)

'包括'只有在多次映射项目时,数组才有用。例如,我们假设您已经映射了一个项目。稍后,您再次映射相同的项目,除了这次,该项目已添加了三个附加属性。默认情况下,Knockout会忽略其他三个属性,因为它们第一次没有。通过自定义' include'数组,你可以强制Knockout映射那些额外的三个属性。

不幸的是,'包括'数组不像你期望的那样充当白名单。

作为解决方法,您可以使用'创建'来自定义映射对象。功能,只包含您想要的属性:

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

小提琴: https://jsfiddle.net/dw1284/g8ca78kc/

答案 1 :(得分:0)

包含

当您将现有 view model映射回JS object时,默认情况下,映射插件仅包含属于existing view model的属性,除非你include那些不是。{/ p>

<强>忽略

如果希望映射插件为您创建视图模型,ignore JS object某些属性,则可以将它们指定为需要忽略的名称数组。 / p>

这就是为什么当您创建view model时,映射插件只会接受您在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);
}