目前我使用jQuery数据存储状态为dom元素.
ko.bindingHandlers.customValue = {
init: function init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var state = { isEditing: false };
$(element).focus(function focus() {
state.isEditing = true;
}).blur(function blur() {
state.isEditing = false;
}).data("customBinding", state);
},
update: function update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
// ignore if updating
if (!$(element).data("customBinding").isEditing) {
// handle update if they are not updating
}
}
};?
Run Code Online (Sandbox Code Playgroud)
是否有更好的地方存储不需要dom的绑定状态?bindingContext可以用于存储绑定的每个实例的状态吗?
RP *_*yer 47
这bindingContext是一种可能性,但仅用于将数据从第一次触发绑定传递init到update第一次.下一次update发射它将不再存在.
存储此类状态的位置实际上有两种选择:
1-正如你所说,在元素上.您可以使用jQuery的$.data或KO包括这样做还有的API ko.utils.domData.get(element, key)和ko.utils.domData.set(element, key, value).
2-如果适用,将此类信息放在视图模型中.要显示的标志isEditing在视图模型中不一定不合适.我个人喜欢将这种类型的"元数据"作为子可观察对象,如下所示:
var name = ko.observable("Bob");
name.isEditing = ko.observable(false);
Run Code Online (Sandbox Code Playgroud)
你将能够绑定name和name.isEditing.
这有一些优点:
nameIsEditing等)ko.toJSON的东西变成JSON时,isEditing只需在它的父元素被解包时被删除.因此,您不会将不必要的值发送回服务器.将数据附加到元素是可以的,并且Knockout在内部使用此方法用于控制流绑定(例如,if,with等).
另一种方法是仅使用该init函数并使用计算的observable来处理更新.我在重复绑定中使用此方法.以下是重要部分:
ko.bindingHandlers['repeat'] = {
'init': function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
...
// set up persistent data
var lastRepeatCount = 0;
...
ko.computed(function() {
var repeatCount = ko.utils.unwrapObservable(valueAccessor());
...
// Remove nodes from end if array is shorter
for (; lastRepeatCount > repeatCount; lastRepeatCount--) {
...
}
...
// Add nodes to end if array is longer (also initially populates nodes)
for (; lastRepeatCount < repeatCount; lastRepeatCount++) {
...
}
}, null, {'disposeWhenNodeIsRemoved': placeholder});
...
}
};
Run Code Online (Sandbox Code Playgroud)