剑道可观察在触发更改事件后不更新

Kendo Observable not Updating after triggering change event

本文关键字:事件 更新 观察      更新时间:2023-09-26

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

我创建了一个清除(取消选中)单选按钮的通用函数。这样做之后,我使用 jQuery 触发更改事件,但可观察模型不会更新它的值。

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。

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

如果不了解框架,我找不到让模型正确更新的方法,所以我做了一些修改,以检查是否定义了剑道或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
});