触发更改事件后,Kendo Observable 未更新

Posted

技术标签:

【中文标题】触发更改事件后,Kendo Observable 未更新【英文标题】:Kendo Observable not Updating after triggering change event 【发布时间】:2013-11-22 01:15:57 【问题描述】:

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

我创建了一个清除(取消选中)单选按钮的通用函数。这样做之后,我使用 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 的键的约定,我能够让模型适当地更新。

【问题讨论】:

请将您的解决方案发布为其他用户的答案 @Entreco 我按照您的要求添加了我的解决方案。 【参考方案1】:

在不了解框架的情况下,我无法找到正确更新模型的方法,因此我进行了一些修改以检查是否定义了剑道或 ko,然后尝试更新模型。这在 kendo 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
);

【讨论】:

以上是关于触发更改事件后,Kendo Observable 未更新的主要内容,如果未能解决你的问题,请参考以下文章

在我单击 Datepicker 控件外部之前,不会触发 Kendo Datepicker 更改事件

每次页面更改和排序都会触发 Kendo 网格的 dataBound 事件

Kendo网格在网格中触发多个控件的数据源事件。(MVVM绑定)

监听 CKEditor 5 中内容更改时触发的事件

剑道网格行选择更改事件?

使用 Kendo UI Mobile 以编程方式触发点击事件