2016-01-26 57 views
1

我有一個模板內的自定義綁定。knockoutjs - 自定義綁定內嵌模板,attr尚未綁定自定義綁定調用

自定義綁定涉及使用綁定到模板的attrs呈現的屬性。

<script type="text/html" id="mc-radio-template"> 
     <!-- ko foreach: Values --> 
     <div class="rounded_col" data-bind="complexRadio: $parent.Value"> 
      <label data-bind="text: Description"></label> 
      <input type="radio" style="visibility:hidden" data-bind="attr: { 'name': $parent.Name, 'value': Value}" /> 
     </div>    
     <!-- /ko --> 
    </script> 

complexRadio涉及模板使用attr綁定呈現的輸入值。

ko.bindingHandlers.complexRadio = { 
    init: function (element, valueAccessor) { 
     // Get radio button located inside this div 
     var radio = $(element).find('input[type="radio"]'); 
     var isDisabled = !!radio.attr('disabled'); 

     var value = valueAccessor(); 
     var valueUnwrapped = ko.utils.unwrapObservable(value); 

     if (valueUnwrapped === true) 
      valueUnwrapped = 'true'; 

     if (valueUnwrapped === false) 
      valueUnwrapped = 'false'; 

     value(valueUnwrapped); 

     // When div is clicked, check the radio and trigger radio change event 
     if (!isDisabled) 
      $(element).click(function() { 
       radio.prop('checked', true); 
       radio.change(); 
      }); 

     // When radio button is checked, update the viewModel property!! 
     $(radio).change(function() { 
      if (radio.prop('checked')) // only if it was changed to checked 
      { 
       // Set viewModel property to value of the radio button that was clicked 
       var value = valueAccessor(); 

       value(radio.val()); 
      } 
     }); 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor) { 
     var value = valueAccessor(); 
     var valueUnwrapped = ko.utils.unwrapObservable(value); 

     if (valueUnwrapped === true) 
      valueUnwrapped = 'true'; 

     if (valueUnwrapped === false) 
      valueUnwrapped = 'false'; 


     // Get radio button located inside this div 
     var radio = $(element).find('input[type="radio"]'); 

     // Set radio to be checked or unchecked 
     var shouldBeChecked = valueUnwrapped == radio.val(); 
     if (shouldBeChecked) 
      radio.parent().addClass('active'); 
     else 
      radio.parent().removeClass('active'); 
    } 
}; 

我的問題是complexRadio init發生在value屬性由模板呈現之前。

在這條線

-

var shouldBeChecked = valueUnwrapped == radio.val(); 

radio.val()不是模板完成渲染之後呈現的一個。 這會導致無線電的開始狀態被取消選中。

如何在渲染結束後強制自定義綁定運行? 也許 - 如何使用js添加自定義綁定,以便我可以將其添加到afterRender回調中。

+0

什麼!在var isDisabled = !! radio.attr('disabled');? – Bindrid

+1

@Bindrid這是一種將值轉換爲布爾值的方法。 – dfperry

+0

你有意將綁定改爲空處理程序,還是你的意思是做radio.trigger('change')或radio.off('change')而不是radio.change()? – Bindrid

回答

1

您在收音機上綁定了一個value,並且您使用jQuery來訪問其value屬性,但收音機在應用外部綁定之後纔會綁定。收音機沒有被渲染是不正確的,它沒有被綁定。

解決方法是讓外部綁定控制所包含廣播的綁定。見the documentation on descendant bindings

+0

我想渲染不是正確的術語,綁定是正確的,它尚未綁定。 –

+0

我沒有完全使用後代綁定,你能舉個例子嗎?我需要在init中使用ko.applyBindingsToDescendants並且應該解決它?工作:) –

+1

是的,從'init'中使用'applyBindingsToDescendants'和'return {controlsDescendantBindings:true};',就像文檔頁面的第二個例子。 –