【问题标题】:knockout chaning binding events淘汰赛更改绑定事件
【发布时间】:2013-09-10 21:58:08
【问题描述】:

目前,我无法触发依赖于淘汰赛中另一个绑定事件结果的绑定事件。

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

但是,问题在于在chain1 输入元素上执行skiplogic 绑定。在“可用”输入被清除其值后,这甚至不会被触发。我怎样才能得到它,以便一个绑定的结果触发另一个绑定?

下面是js fiddle版本的代码: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:

// 此屏幕的整体视图模型,以及初始状态 函数预订视图模型(){ 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());

【问题讨论】:

    标签: javascript jquery events knockout.js


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 你能说得详细一点吗?为什么skiplogic: available on the 'chain1' input 当'available'输入被这段代码清除时没有被触发: if (isSkipped) { eval("viewModel." + id + "('');") ; $(element).attr("禁用", "禁用"); } else { if (elementSkipped[id] > 0) { $(element).attr("disabled", "disabled"); } else { $(element).removeAttr("disabled"); } }
    • 这里有几个问题。首先,您在 chain1 元素上指定了 skiplogic 而不是 skipLogic。绑定区分大小写。其次对于emptynotempty 条件,您将需要访问可观察对象的值来创建依赖项。因此,与其从字段中读取值,不如使用:viewModel[conditions[i].Condition]()。此语法将允许您动态指定要访问的属性名称,而无需执行 eval 之类的操作。此外,您还有一个未定义的 elementSkipped 变量。
    • 这里只是修复了这些问题:jsfiddle.net/rniemeyer/4jbb5。总的来说,我认为使用计算的可观察对象将此逻辑放入视图模型中,然后对元素使用普通绑定(以启用/禁用元素)可能是更好的情况。
    • 感谢您回答我的问题。您能否提供有关使用 viewModel[conditions[i].Condition]() 创建值依赖项的文档的位置?
    • 这是使用括号符号来访问属性。此链接可能有助于为您提供一些信息:developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/…。因此,您可以访问对象的成员,例如 viewModel.blahviewModel['blah']。在这种情况下,因为我们有一个动态字符串,括号表示法让我们可以访问我们想要的属性,并将它作为一个函数调用(它是一个可观察的)给我们返回值,这也创建了一个依赖项。希望对您有所帮助。
    【解决方案2】:

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

    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/

    【讨论】:

    • 注意,Knockout 太棒了,它只会在表达式的结果改变值时调用这个绑定!这是我在编写此功能时了解到的一个小事实。
    猜你喜欢
    • 2022-10-17
    • 1970-01-01
    • 2013-02-04
    • 2013-08-17
    • 2013-11-14
    • 2013-05-04
    • 1970-01-01
    • 2018-08-04
    • 2014-04-28
    相关资源
    最近更新 更多