如何使用敲除映射从空值映射到空的可观察数组?
How do you use knockout mapping to map from a null value to an empty observable array?
我在尝试使用敲除映射从空 json 属性 映射到敲除可观察数组时遇到问题。映射完成后,敲除数组为空。
因此,例如,我有以下数据:
var data = { 'Name': 'David', 'Modules': null };
以及以下型号:
var ModuleViewModel = function(data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
};
var Model = function(data) {
var self = this;
var mapping = {
'Modules': {
key: function(module) {
return ko.utils.unwrapObservable(module.Id);
},
create: function (options) {
return new ModuleViewModel(options.data);
}
}
};
ko.mapping.fromJS(data, mapping, self);
};
然后应用到视图使用:
var model = new Model(data);
ko.applyBindings(model);
在视图中,只需:
<span data-bind="text: Name"></span>
<span data-bind="text: Modules().length"></span>
我想看到的(在我的名字之后)是已映射的模块数。如果数据中存在模块:
var data = { 'Name': 'David', 'Modules': [ {'Id': '1', 'Name': 'Module1'} ] }
然后正确的数字显示在视图上,但如果模块在数据中设置为 null,则数字根本不会显示,因为它不知道映射到可观察数组。
此外,如果我在我的视图模型上定义一个额外的 属性 映射到:
self.Modules = ko.observableArray;
这仍然没有像我预期的那样被映射,就好像你在映射之后查询 self.Modules()
你得到一个 null
返回的值,如果你查询一个普通的空可观察数组你得到 []
返回。
我在映射中做错了什么?我只想在模块数据为空时显示 0 值。
您可以放置一个计算的可观察对象进行空值检查并尽可能保持干净,如下所示:
var ModuleViewModel = function(data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
//After mapping the object, add the computed observable here
self.numberOfModules = ko.computed(function() {
return this.Modules ? this.Modules().length : 0;
}, self);
};
然后在你的绑定中:
<span data-bind="text: numberOfModules">
如果 computed 在 HTML 中的许多不同地方使用以避免在任何地方重复空检查,这将特别方便。
这里有一些您可能会觉得有用的映射更新。
请务必注意以下更改。
一方面,您没有应用映射。
// need to invoke the mapping object
ko.mapping.fromJS(data, mapping, self);
其次,用 null 调用 observable 没有多大意义……这就像吃甜甜圈的洞,对吧?
//Initialize your data with null modules :: ERROR
//For the sake of having an empty observable array, we need to convert this null to an empty array
var data = { 'Name': 'David', 'Modules': null };
if(data.Modules == null) data.Modules = [];
第三,如果你可能得到空值,你应该继续添加一点短路逻辑来防止它...
var mapping = {
'Modules': {
create: function (options) {
if(options.data !== null)
return new ModuleViewModel(options.data);
}
}
};
总而言之,地图插件很好用,但没有什么神奇的地方……还是要确保你的数据是合理的。
我在尝试使用敲除映射从空 json 属性 映射到敲除可观察数组时遇到问题。映射完成后,敲除数组为空。
因此,例如,我有以下数据:
var data = { 'Name': 'David', 'Modules': null };
以及以下型号:
var ModuleViewModel = function(data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
};
var Model = function(data) {
var self = this;
var mapping = {
'Modules': {
key: function(module) {
return ko.utils.unwrapObservable(module.Id);
},
create: function (options) {
return new ModuleViewModel(options.data);
}
}
};
ko.mapping.fromJS(data, mapping, self);
};
然后应用到视图使用:
var model = new Model(data);
ko.applyBindings(model);
在视图中,只需:
<span data-bind="text: Name"></span>
<span data-bind="text: Modules().length"></span>
我想看到的(在我的名字之后)是已映射的模块数。如果数据中存在模块:
var data = { 'Name': 'David', 'Modules': [ {'Id': '1', 'Name': 'Module1'} ] }
然后正确的数字显示在视图上,但如果模块在数据中设置为 null,则数字根本不会显示,因为它不知道映射到可观察数组。
此外,如果我在我的视图模型上定义一个额外的 属性 映射到:
self.Modules = ko.observableArray;
这仍然没有像我预期的那样被映射,就好像你在映射之后查询 self.Modules()
你得到一个 null
返回的值,如果你查询一个普通的空可观察数组你得到 []
返回。
我在映射中做错了什么?我只想在模块数据为空时显示 0 值。
您可以放置一个计算的可观察对象进行空值检查并尽可能保持干净,如下所示:
var ModuleViewModel = function(data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
//After mapping the object, add the computed observable here
self.numberOfModules = ko.computed(function() {
return this.Modules ? this.Modules().length : 0;
}, self);
};
然后在你的绑定中:
<span data-bind="text: numberOfModules">
如果 computed 在 HTML 中的许多不同地方使用以避免在任何地方重复空检查,这将特别方便。
这里有一些您可能会觉得有用的映射更新。
请务必注意以下更改。
一方面,您没有应用映射。
// need to invoke the mapping object
ko.mapping.fromJS(data, mapping, self);
其次,用 null 调用 observable 没有多大意义……这就像吃甜甜圈的洞,对吧?
//Initialize your data with null modules :: ERROR
//For the sake of having an empty observable array, we need to convert this null to an empty array
var data = { 'Name': 'David', 'Modules': null };
if(data.Modules == null) data.Modules = [];
第三,如果你可能得到空值,你应该继续添加一点短路逻辑来防止它...
var mapping = {
'Modules': {
create: function (options) {
if(options.data !== null)
return new ModuleViewModel(options.data);
}
}
};
总而言之,地图插件很好用,但没有什么神奇的地方……还是要确保你的数据是合理的。