我有一个<span>
,上面有几个绑定。 enable
和click
。
<span data-bind="enable: buttonEnabled, click: takeAnAction">Take An Action</span>
我可以写一个自定义绑定处理程序,或者当click
绑定为false时,是否有另一种简单的方法让enable
绑定尊重(而不是行动)?
我知道我可以在if
操作中添加click
语句,但如果我可以自动执行此操作而不在我的视图中添加额外的逻辑,那就太棒了。
答案 0 :(得分:2)
您似乎从评论中更新了问题。如果您使用支持被禁用的按钮或输入元素,那么这将自然适合您。
如果您确实需要使用类似span
的内容,那么您可以编写一个快速自定义绑定,将其包装在条件检查中:
ko.bindingHandlers.clickIf = {
init: function(element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor()),
wrappedHandler;
if (options && options.condition && typeof options.action === "function") {
wrappedHandler = function(data, event) {
if (ko.utils.unwrapObservable(options.condition)) {
options.action.call(data, data, event);
}
};
ko.applyBindingsToNode(element, { click: wrappedHandler });
}
}
};
您可以使用它:
<span data-bind="clickIf: { action: test, condition: isEnabled }">Test</span>
答案 1 :(得分:1)
以RP Niemeyer's answer为基础。一个更简单(但不易扩展的解决方案)是直接在自定义绑定处理程序中引用元素enable
属性。
ko.bindingHandlers.clickIfEnabled = {
init: function(element, valueAccessor, allBindingsAccessor) {
var action = ko.utils.unwrapObservable(valueAccessor()),
wrappedHandler = function(data, event) {
if (allBindingsAccessor().enable()) {
action.call(data, data, event);
}
};
ko.applyBindingsToNode(element, { click: wrappedHandler });
}
};
像这样使用:
<span data-bind="enable: isEnabled, clickIfEnabled: test">Test</span>
此方法仅允许您更改一个标准绑定。 click
至clickIfEnabled
。
答案 2 :(得分:0)
例如,此绑定仅评估'condition'表达式一次(执行init回调时),并且当observables的值发生更改时无法正常工作:
<span data-bind="clickIf: { action: doSomething, condition: (isEnabled() == true && anotherObservable() == true) }">Test</span>
为了使此绑定接受包含observable的表达式,并根据该表达式的最新值正确执行,您需要重构绑定处理程序,如下所示:< /强>
ko.bindingHandlers.clickIf = {
init: function (element, valueAccessor) {
// Hold state of options so that the 'update' callback can effectively
// 'pass in' new evaluated 'condition' expressions (as observables change) to the wrappedHandler.
element.ko_clickIfOptions = ko.utils.unwrapObservable(valueAccessor());
var wrappedHandler = function (data, event) {
// "ko_clickIfOptions.condition" will get us the current value of a 'condition'
// expression since the 'update' callback updates these options
var condition = ko.utils.unwrapObservable(element.ko_clickIfOptions.condition);
if (condition) {
element.ko_clickIfOptions.action.call(data, data, event);
}
};
ko.applyBindingsToNode(element, { click: wrappedHandler });
},
// When the value of any observable in your expression changes, we grab 'options'
// again so that the wrappedHandler will have the latest value of the expression
update: function (element, valueAccessor) {
element.ko_clickIfOptions = ko.utils.unwrapObservable(valueAccessor());
}
};
通过此实现,即使“条件”表达式中的任何可观察对象发生更改,上面列出的示例也能正常运行。