淘汰更改绑定事件

时间:2013-09-06 18:03:02

标签: javascript jquery events knockout.js

目前我无法触发依赖于敲除中另一个绑定事件结果的绑定事件。

在下面的示例中,在'available'输入中提供一个值,当'condition1'输入填充一个值,例如22时,应该清除和禁用'available'输入,所有这一切都在跳过逻辑绑定。这种情况正常发生。

然而,问题在于对chain1输入元素执行skiplogic绑定。在“可用”输入清除其值后,甚至不会触发此操作。我如何得到它,以便一个绑定的结果触发另一个绑定?

以下是代码的js小提琴版:http://jsfiddle.net/gYNb8/2/

以下是我用来测试概念的表格:

<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<span>Condition 1</span> 
<input id="condition1" data-bind="value: condition1" />
<br/>
<span>Condition 2</span> 
<input id="condition2" data-bind="value: condition2" />
<br/>
<span>Available?</span> 
<input id="available" data-bind="value: available, skipLogic: condition1, skipLogic: condition2" />
<br/>
<span>Chain1</span> 
<input id="chain1" data-bind="value: chain1, skiplogic: available" />

这是javascript:

//此屏幕的整体viewmodel以及初始状态     function ReservationsViewModel(){         var self = this;

    self.condition1 = ko.observable();
    self.condition2 = ko.observable();
    self.available = ko.observable();
    self.chain1 = ko.observable();

}

//Here are the conditions which govern whether an element should be enabled or not
var elementConditions = {
    'available': [{
        'Condition': 'condition1() > 0',
        'Type': 'evaluation'
    }, {
        'Condition': 'condition2() > 0',
        'Type': 'evaluation'
    }],
        'chain1': [{
        'Condition': 'available',
        'Type': 'empty'
    }]
};


ko.bindingHandlers.skipLogic = {
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {


        var id = $(element).attr("id");
        var conditions = elementConditions[id];
        var isSkipped = false;
        var conditionMet = false;

        for (var i = 0; i < conditions.length; i++) {
            conditionMet = false;
            if (conditions[i].Type == "evaluation") {
                conditionMet = eval('viewModel.' + conditions[i].Condition);
            } else if (conditions[i].Type == "empty") {
                if ($('#' + conditions[i].Condition).val().length == 0) {
                    conditionMet = true;
                }
            } else if (conditions[i].Type == "notempty") {
                if ($('#' + conditions[i].Condition).val().length > 0) {
                    conditionMet = true;
                }
            }

            if (conditionMet == true) {
                isSkipped = true;
            }
        }

        if (isSkipped) {
            eval("viewModel." + id + "('');");            
            $(element).attr("disabled", "disabled");
        } else {
            if (elementSkipped[id] > 0) {
                $(element).attr("disabled", "disabled");
            } else {
                $(element).removeAttr("disabled");
            }
        }
    }
};

ko.applyBindings(new ReservationsViewModel());

2 个答案:

答案 0 :(得分:0)

绑定的update函数将在元素首次绑定时执行(在init函数之后),然后在其任何依赖项发生更改时再次运行。您可以通过访问函数内的observable来创建依赖项(比如计算内部,因为计算机实际上用于促进绑定更新)。

因此,您需要确保通过调用valueAccessor()来访问检索传递给绑定的任何内容,然后如果值是可观察的,则您希望将其作为函数来调用它来检索值。否则,如果您不确定自己是否已通过观察,则可以致电ko.unwrap(2.3之前为ko.utils.unwrapObservable - 可以使用2.3之后的任何内容。)

此外,您可以使用allBindingsAccessor参数(第三个参数)或直接访问数据(第4个参数)或上下文(第5个参数)来访问传递给其他绑定的值。

使用相同元素的相同名称传递多个绑定是行不通的。您可能需要考虑以不同方式构造它,例如传递数组data-bind="skipLogic: [one, two]",然后访问每个数组的值。

答案 1 :(得分:0)

您可以使用布尔逻辑在绑定中将它们串在一起,而不是尝试单独保留条件吗?这样您就不需要跟踪每个绑定状态。我构建了以下绑定:

ko.bindingHandlers.skipLogic = {
init: function(element, valueAccessor) {
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
    var valueOfCondition = ko.unwrap(valueAccessor());
    var jqElement = $(element);       

//update if the field is disabled if more than one condition is met        
        if(valueOfCondition){
            jqElement.prop('disabled', true);
        }
        else{
            jqElement.prop('disabled', false);
        }
     }
};

这里有一个工作示例:http://jsfiddle.net/M7vUV/3/