触发更改事件后,Kendo Observable不会更新

时间:2013-11-10 03:35:58

标签: javascript jquery mvvm kendo-ui

我要求允许用户取消选中单选按钮。

我创建了一个清除(取消选中)单选按钮的常规功能。在这样做之后,我使用jQuery触发change事件,但Observable模型不会更新它的值。

var UnCheck = "UnCheck";

$("input:radio.AllowUnCheck").click(function(event){

    var $clickedbox = $(this),
        radioname = $clickedbox.prop("name"),
        $group = $('input[name|="'+ radioname + '"]'),
        doUncheck = $clickedbox.hasClass(UnCheck),
        isChecked = $clickedbox.is(':checked');

    if(doUncheck){

        $group.removeClass(UnCheck);
        $clickedbox.prop('checked', false);

        //Edit: Added this code as a work around. 
        if(kendo)if(this.kendoBindingTarget){

            bindingSource = this.kendoBindingTarget.source;
            if(bindingSource){

                try{
                    // This assumes that the name of the radio group is the same as the
                    // as the observables key (set and get key).
                    bindingSource.set(radioname, "None");
                }
                catch(e){/*Do nothing*/}
            }
        };
    }
    else if(isChecked){

        // Make sure that others in the group do not have the UnCheck class
        // This will ensure that only one radio in the group will have the UnCheck class at a time.
        $group.removeClass(UnCheck);

        // Adding the class tells the function to uncheck it the next time this radio
        // is clicked, if clicked before any other radio in the group is clicked.
        $clickedbox.addClass(UnCheck);
    }
    //$clickedbox.trigger("change");
    document.getElementById(this.id).onchange();
});

我还尝试了快捷方式$clickedbox.change()document.getElementById("id").onchange();

那么当我用JavaScript更改值时,如何让Observable用UI更新它的值?

请记住,进行更改的代码不知道该元素绑定到了一个kendo Observable,并且不能依赖于kendo-ui API。

编辑:我找不到解决方法,所以我添加了代码来检查kendo可观察绑定。遵循使用无线电组名称作为访问相应observable的键的惯例,我能够使模型适当更新。

1 个答案:

答案 0 :(得分:1)

在没有框架知识的情况下,我找不到让模型正确更新的方法,所以我做了一些修改,以检查是否定义了kendo或ko,然后尝试更新模型。这对我来说在剑道MVVM中有用,但我还没有在淘汰赛中审查它。如果有人对如何改进这一点有任何建议,请告诉我。

/**
 * Depends on jQuery.
 */
var AllowRadioUnCheck = new function(){

    var PUBLIC=this,
        UnCheck = "UnCheck",
        className = "AllowRadioUnCheck";

    /**
     * @returns {string} The class name that is added to a radio input to
     * indicate that it should be unchecked the next time it is clicked.
     */
    function getUnCheck(){

        return UnCheck;
    }
    PUBLIC.getUnCheck =  getUnCheck;

    /**
     * @returns {string} The class name for AllowRadioUnCheck, to indicate that the radio group should
     * allow the user to uncheck values. The class needs to be added to each element in the named group.
     */
    function getAllowRadioUnCheck(){

        return className;
    }

    PUBLIC.getAllowRadioUnCheck = getAllowRadioUnCheck;

    /**
     * @param data_bind (string) The data_bind parameter value for the element.
     * @returns {*} The model name/key that is bound to the "checked" binding.
     */
    function getModelBind(data_bind){

        if(data_bind){

            var checkedIndex = data_bind.indexOf("checked:");
            if(checkedIndex >= 0){
                checkedIndex += 8;
            }
            else{
                checkedIndex = 0;
            }
            var targetEnd = data_bind.indexOf(",",checkedIndex);
            if(targetEnd < checkedIndex){
                targetEnd = data_bind.length;
            }
            var key = $.trim(data_bind.substring(checkedIndex, targetEnd));

            return key;
        }
        else{
            return "";
        }
    }

    /**
     * This should be called after any MVVM data binding, and after the class has been added to all appropriate elements,
     * if you are adding the class programatically with jQuery or JavaScript,m as opposed to in line.
     */
    function bind(){

        $("input:radio.AllowRadioUnCheck").click(function(event){

            var $clickedbox = $(this),
                radioname = $clickedbox.prop("name"),
                $group = $('input[name|="'+ radioname + '"]'),
                doUnCheck = $clickedbox.hasClass(UnCheck),
                isChecked = $clickedbox.is(':checked'),
                data_bind = $clickedbox.data('bind'),
                bindingSource = null,
                $koData = null;

            if(doUnCheck){

                $group.removeClass(UnCheck);
                $clickedbox.prop('checked', false);
                try{
                    if(kendo)if(this.kendoBindingTarget){

                        bindingSource = this.kendoBindingTarget.source;

                        if(bindingSource){
                            var modelKey = getModelBind(data_bind);
                            bindingSource.set(modelKey, "None");
                            /*TODO: Needs more testing to determine whether dependant observables are updating properly.
                                I may need to add some kind of change event notification here.
                            */
                        }
                    };
                }
                catch(e){/*Do nothing*/}
                try{
                    // Has not been tested for proper knockout functionality yet.
                    // Let me know if this works for you if you are using knockout.
                    if(ko){

                        $koData = ko.dataFor(this);
                        $koData("None");
                        $koData.valueHasMutated();//Make sure computed update properly.
                    }
                }
                catch(e){/*Do nothing*/}
            }
            else if(isChecked){

                // Make sure that others in the group do not have the UnCheck class
                // This will ensure that only one radio in the group will have the UnCheck class at a time.
                $group.removeClass(UnCheck);

                // Adding the class tells the function to uncheck it the next time this radio
                // is clicked, if clicked before any other radio in the group is clicked.
                $clickedbox.addClass(UnCheck);
            }

        });
        $("input:radio.AllowRadioUnCheck:checked").addClass(UnCheck);
    }
    PUBLIC.bind = bind;
}

另外,我想我会加上这一点来说明如何使用它。

HTML:

<input type=radio" name="MyRadio" id="One" value="One" class="AllowRadioUnCheck"/>
<input type=radio" name="MyRadio" id="Two" value="Two" class="AllowRadioUnCheck"/>

JavaScript的:

$(document).ready(function(){

    AllowRadioUnCheck.bind();
    //I prefer allowing the developer to decide when to bind the class functionality
});