敲除映射选项不排除源对象的附加属性
Knockout mapping options not excluding additional properties from source object
在我的视图模型中,我声明了一个名为 'MappedItem':
的可观察对象 属性
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' 有很多无用的可观察属性。
为了得到我想要的东西,我必须在映射选项对象的 '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' 选项中显式声明它们吗?
包括
当您将 现有 view model
映射回 JS object
时,默认情况下,映射插件仅包含属于您 existing view model
,除非你include
那些不是。
忽略
当你想 ignore
你的一些属性时 JS object
一旦你希望映射插件为你创建一个视图模型,你可以将它们指定为需要忽略的名称数组.
这就是为什么当您创建 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);
}
'include' 数组仅在多次映射一个项目时才有用。例如,假设您已经映射了一个项目。稍后,您再次映射同一个项目,除了这次,三个额外的属性已添加到该项目。默认情况下,Knockout 会忽略这三个额外的属性,因为它们第一次不存在。通过自定义 'include' 数组,您可以强制 Knockout 映射这三个额外的属性。
不幸的是,'include' 数组并不像您期望的那样充当白名单。
作为解决方法,您可以使用 'create' 函数自定义映射对象,并且只包含您需要的属性:
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);
在我的视图模型中,我声明了一个名为 'MappedItem':
的可观察对象 属性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' 有很多无用的可观察属性。
为了得到我想要的东西,我必须在映射选项对象的 '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' 选项中显式声明它们吗?
包括
当您将 现有 view model
映射回 JS object
时,默认情况下,映射插件仅包含属于您 existing view model
,除非你include
那些不是。
忽略
当你想 ignore
你的一些属性时 JS object
一旦你希望映射插件为你创建一个视图模型,你可以将它们指定为需要忽略的名称数组.
这就是为什么当您创建 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);
}
'include' 数组仅在多次映射一个项目时才有用。例如,假设您已经映射了一个项目。稍后,您再次映射同一个项目,除了这次,三个额外的属性已添加到该项目。默认情况下,Knockout 会忽略这三个额外的属性,因为它们第一次不存在。通过自定义 'include' 数组,您可以强制 Knockout 映射这三个额外的属性。
不幸的是,'include' 数组并不像您期望的那样充当白名单。
作为解决方法,您可以使用 'create' 函数自定义映射对象,并且只包含您需要的属性:
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);