在我的一个项目中,我一直在使用KnockoutJS 2.2.1。我一直在使用自定义指令通过滑动动画对象变化,如下所示:
ko.bindingHandlers.withSliding = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
return ko.bindingHandlers.with.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
slideOut(function () {
ko.bindingHandlers.with.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
slideIn();
});
}
};
现在我想更新到Knockout 3.1.0。但问题是:“with”绑定现在缺少“ko.bindingHandlers.with”的“update”子属性。因此,无法推迟模板更新。
任何解决方案?
提前谢谢。
答案 0 :(得分:1)
我可以想到几个选项:
如果你不关心过渡(你似乎要滑出来,所以你可能会照顾),那么你可以在里面的第一个元素上放一个简单的slideIn
绑定具有with
绑定的容器。在绑定的init
函数中,您可以隐藏元素,然后将其滑入。
否则,您可以选择包装template
绑定而不是with
绑定。如果将选项对象传递给template
绑定并排除name
属性,则它将使用子元素作为其匿名模板。
在update
函数中,您还需要确保同步访问任何可观察的依赖项(不仅仅是在异步回调中),以便它再次触发。
可能是这样的:
ko.bindingHandlers.templateSliding = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
return ko.bindingHandlers.template.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var data, options = ko.unwrap(valueAccessor());
if (options && options.data) {
//make sure that we have a dependency on the template's data
data = ko.unwrap(options.data);
}
$(element).slideUp("fast", function () {
ko.bindingHandlers.template.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
if (data) {
$(element).slideDown();
}
});
}
};
答案 1 :(得分:1)
通常,Knockout不支持直接调用绑定处理程序的init
和update
函数。在Knockout 3.1中,with
绑定在其init
函数中进行了所有更新,因此无论如何都无法拦截它。
Knockout确实提供了一种绑定标准方式来拦截添加或删除的内容 - foreach
绑定。从Knockout 3.0开始,还有一种方法可以使用preprocess
function来包装其他绑定。将这两者放在一起,这就是withSliding
绑定的样子:
ko.bindingHandlers.withSliding = {
preprocess: function (value, name, addBinding) {
addBinding('foreach',
'{'+
'data:[ko.unwrap('+ value +')],'+
'beforeRemove:function(elem) { if (elem.nodeType === 1) $(elem).slideUp(function() { $(elem).remove(); })},'+
'afterAdd:function(elem) { if (elem.nodeType === 1) $(elem).hide().slideDown()}'+
'}'
);
}
};
jsFiddle:http://jsfiddle.net/mbest/wRbzL/(使用RP Niemeyer的模板)
或者,您的自定义绑定可以执行所有操作(不包装任何其他绑定)。
ko.bindingHandlers.withSliding = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var $element = $(element),
template = $element.children().clone();
$element.hide();
ko.computed(function() {
var dataValue = ko.unwrap(valueAccessor());
$element.slideUp(function () {
$element.empty();
if (dataValue) {
$element.append(template.clone()).hide();
ko.applyBindingsToDescendants(bindingContext.createChildContext(dataValue), element);
$element.slideDown();
}
});
}, null, { disposeWhenNodeIsRemoved: element });
return { controlsDescendantBindings: true };
}
};
jsFiddle:http://jsfiddle.net/mbest/pzsCX/