2013-11-10 34 views
2

后不更新我有允许用户取消选中单选按钮的要求。剑道可观察触发改变事件

我已经创建了清零(取消选中)单选按钮一般功能。这样做后,我使用jQuery触发更改事件,但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();

那么如何我得到的可观测来更新它与UI值时,我已经改变了使用JavaScript的价值?

请记住,这使得变化的代码不知道该元素绑定到剑道观察的,而不能依赖于剑道的UI API。

编辑:我无法找到一个办法解决,所以我加了代码来检查剑道观察到的绑定。继使用的无线电组名称作为访问关键的约定相应的观察到的,我能得到的模型来适当地更新。

+0

请发表您的解决方案作为一个答案为其他用户 – Entreco

+1

@Entreco我说我的解决方案为您的要求。 – Pytry

回答

1

我无法找到一个办法让这些模型没有框架的知识来正确地更新,所以我做了一些修改,以检查是否剑道或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 
});