1

我有一个<span>带有几个绑定的。enable, 和click.

<span data-bind="enable: buttonEnabled, click: takeAnAction">Take An Action</span>

是否有我可以编写的自定义绑定处理程序,或者当绑定为假时让click绑定尊重(而不是行动)的另一种简单方法?enable

我知道我可以if在操作中添加一个语句click,但如果我可以自动执行此操作而不向我的视图添加额外的逻辑,那就太好了。

4

3 回答 3

2

看起来您更新了评论中的问题。如果您使用支持禁用的按钮或输入元素,那么这对您自然有效。

如果您确实需要使用类似 a 的东西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>

示例:http: //jsfiddle.net/rniemeyer/LZTtE/

于 2013-05-14T18:18:51.333 回答
1

基于RP Niemeyer 的回答。一个更简单(但扩展性较差的解决方案)是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>

此方法只允许您更改一个标准绑定。clickclickIfEnabled.

示例:http: //jsfiddle.net/LZTtE/6/

于 2013-05-14T19:18:55.393 回答
0

RP Niemeyer 的回答是迈向可扩展解决方案的良好开端。但是,它不允许您在“条件”选项中包含包含可观察对象的表达式,当这些可观察对象随时间变化时,它将被重新评估。

例如,此绑定只计算一次“条件”表达式(当 init 回调执行时),并且随着可观察值的变化而无法正常工作:

<span data-bind="clickIf: { action: doSomething, condition: (isEnabled() == true && anotherObservable() == true) }">Test</span>

为了让这个绑定接受包含 observables 的表达式,并根据该表达式的最新值正确执行,您需要像这样重构绑定处理程序:

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());
    }
};

使用此实现,即使“条件”表达式中的任何可观察值发生变化,上面列出的示例也可以正确运行。

于 2013-11-01T19:01:18.917 回答