2013-11-10 32 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 
});