All*_*ice 56 javascript mvvm knockout-mapping-plugin knockout.js
我还在学习Knockout的正确使用方法,并且我发现自己ko.observable在设置我的viewmodel时很快就远离了键入,而只是定义了一个对象文字,并通过映射插件传递给它
var viewModel = ko.mapping.fromJS(data);
Run Code Online (Sandbox Code Playgroud)
或者至少,将所有数据填充到viewModel上的属性中,就像这样
var viewModel = {
... events etc ... ,
"data": ko.mapping.fromJS(data)
}
Run Code Online (Sandbox Code Playgroud)
说实话,我一直这样做的主要原因是为了解决必须打字ko.observable和ko.observableArray重复的问题.我只是想弄清楚这是否是一个好方法,如果有任何缺点,将var x = ko.observable()所有特定声明放在一起.此外,我正在加载所有这些,而不是响应任何ajax调用等,从我可以看出,这是映射插件的设计目的.
在使用knockout的工作中,你是否仍然手动逐个声明observable,或者你使用了我使用的mapping.fromJS方法?像这样经常使用映射插件有什么特别的缺点吗?
编辑:
在本文中,Steve通过这样做来设置他的viewModel
var initialData = [ { ... } , { ... } ]; // json from the serializer
var viewModel = {
gifts : ko.observableArray(initialData)
};
Run Code Online (Sandbox Code Playgroud)
通常,我也只是ko.mapping.fromJS用于这种情况,特别是为了确保数组中的对象也被转换为可观察对象.看看他做了什么,我的做法似乎有些过度,并增加了一些不必要的开销.
All*_*ice 59
在使用Knockout一段时间后,我注意到映射插件有一些额外的选项,可以让您对映射过程进行更精细的控制.
有几种方法可以实现这一点,我将讨论一些,但最终结果是你最终得到了映射插件的更轻的结果,因为一切都是不可观察的.
基本上,你把你认为不会改变的一切都留作普通的属性,只能从你想要观察的特定项目中做出可观察的.
mapping忽略某些属性您可以通过指定诸如ignore或之类的内容使映射插件完全从最终结果中省略属性include.这两者都以相反的方式完成了同样的事情.
注意:样本来自knockout.js映射插件文档,我添加了评论
include以下代码段将省略源对象中除通过include参数传入的属性之外的所有属性.
// specify the specific properties to include as observables in the end result
var mapping = {
// only include these two properties
'include': ["propertyToInclude", "alsoIncludeThis"]
}
// viewModel will now only contain the two properties listed above,
// and they will be observable
var viewModel = ko.mapping.fromJS(data, mapping);
Run Code Online (Sandbox Code Playgroud)
ignore如果只想省略源对象中的某些属性,请使用ignore如下所示的参数.除了指定的属性外,它将从源对象中的所有属性创建可观察对象.
// specify the specific properties to omit from the result,
// all others will be made observable
var mapping = {
// only ignore these two properties
'ignore': ["propertyToIgnore", "alsoIgnoreThis"]
}
// viewModel will now omit the two properties listed above,
// everything else will be included and they will be an observable
var viewModel = ko.mapping.fromJS(data, mapping);
Run Code Online (Sandbox Code Playgroud)
如果你需要包含属性,但你不认为它们需要被观察(无论出于何种原因),那么映射插件可以提供帮助.
copy如果您希望映射插件只是简单地复制普通属性而不使它们可观察,请使用此参数,如下所示.
// tell the mapping plugin to handle all other properties normally,
// but to simply copy this property instead of making it observable
var mapping = {
'copy': ["propertyToCopy"]
}
var viewModel = ko.mapping.fromJS(data, mapping);
Run Code Online (Sandbox Code Playgroud)
如果您希望100%控制映射过程中创建的内容,包括在对象中放置闭包和订阅的功能,那么您需要使用"创建"选项.
这是一个示例,我将数据从ajax调用映射到具有results属性的对象.我不想要任何可观察的东西,我只想要一个简单的生成属性,它将由对象上的其他简单属性组成.也许不是最引人注目的例子,但它展示了功能.
var searchMappingConfig = {
// specific configuration for mapping the results property
"results": {
// specific function to use to create the items in the results array
"create": function (options) {
// return a new function so we can have the proper scope/value for "this", below
return new function () {
// instead of mapping like we normally would: ko.mapping.fromJS(options.data, {}, this);
// map via extend, this will just copy the properties from the returned json element to "this"
// we'll do this for a more light weight vm since every last property will just be a plain old property instead of observable
$.extend(this, options.data);
// all this to add a vehicle title to each item
this.vehicleTitle = this.Year + "<br />" + this.Make + " " + this.Model;
}, this);
};
}
}
}
Run Code Online (Sandbox Code Playgroud)
另一种情况是,如果您想在结果中使用闭包和订阅.此示例太长,无法完整地包含在内,但它适用于车辆品牌/模型层次结构.如果模型未启用,我希望取消启用给定make(父)的所有模型(子项),并且我希望通过订阅完成此操作.
// here we are specifying the way that items in the make array are created,
// since makes has a child array (Models), we will specify the way that
// items are created for that as well
var makesModelsMappingConfig = {
// function that has the configuration for creating makes
"create": function (options) {
// return a new function so we can have the proper
// scope/value for "this", below
return new function () {
// Note: we have a parent / child relationship here, makes have models. In the
// UI we are selecting makes and then using that to allow the user to select
// models. Because of this, there is going to be some special logic in here
// so that all the child models under a given make, will automatically
// unselect if the user unselects the parent make.
// make the selected property a private variable so it can be closure'd over
var makeIsSelected = ko.protectedComputed(false);
// expose our property so we can bind in the UI
this.isSelected = makeIsSelected;
// ... misc other properties and events ...
// now that we've described/configured how to create the makes,
// describe/configure how to create the models under the makes
ko.mapping.fromJS(options.data, {
// specific configuration for the "Models" property
"Models": {
// function that has the configuration for creating items
// under the Models property
"create": function (model) {
// we'll create the isSelected as a local variable so
// that we can flip it in the subscription below,
// otherwise we wouldnt have access to flip it
var isSelected = ko.protectedComputed(false);
// subscribe to the parents "IsSelected" property so
// the models can select/unselect themselves
parentIsSelected.current.subscribe(function (value) {
// set the protected computed to the same
// value as its parent, note that this
// is just protected, not the actual value
isSelected(value);
});
// this object literal is what makes up each item
// in the Models observable array
return {
// here we're returning our local variable so
// we can easily modify it in our subscription
"isSelected": isSelected,
// ... misc properties to expose
// under the item in the Model array ...
};
}
}
}, this);
};
}
};
Run Code Online (Sandbox Code Playgroud)
总而言之,我发现你很少需要100%的对象传递给插件,而你很少需要100%的对象可以观察到.深入了解映射配置选项并创建各种复杂和简单的对象.我们的想法是只获得您需要的一切,无论是更多还是更少.
pho*_*tom 22
我给你的建议也是另一个问题,我刚才在/sf/ask/524939341/上回答.
您使用映射插件的原因是合理的,也是我使用的插件.为什么要输入比你更多的代码?
根据我的淘汰经验(全部4个月),我发现我手动做的越少,让淘汰程序做他们的事情,我的应用程序似乎运行得越好.我的建议是先尝试最简单的方法.如果它不能满足您的需求,请查看简单方法如何做"事情"并确定必须更改以满足您的需求.
| 归档时间: |
|
| 查看次数: |
14732 次 |
| 最近记录: |