2016-12-28 21 views
-1

我做了一個小的小提琴證明了我的問題在這裏創建http://jsfiddle.net/LkqTU/33025/引用一個標識在淘汰賽組件

的日期選擇器是採用在組件不火

下面是我原來的職位...

我正在使用bootstrap 3日期時間選擇器,它的工作方式如下。

HTML

<div data-bind="css: formControlCss"> 
               <label class="control-label" for="earlyPickup">Early Pickup:</label> 
                <div class='input-group date' id='earlyPickup'> 
                <input type='text' class="form-control" /> 
                <span class="input-group-addon"> 
                 <span class="glyphicon glyphicon-calendar"></span> 
                </span> 
                </div> 
              </div> 

的JavaScript。

$('#earlyPickup').datetimepicker(
            { 
            defaultDate: d.DB2VXRVSMRecord.DtErlstPickup + " " + d.DB2VXRVSMRecord.TiErlstPickup 
            }); 

這工作得很好,但是我有幾個這樣的日期時間選擇器,所以我試圖創建一個淘汰賽的組成部分。

組件。

ko.components.register('datetime-picker', { 
      viewModel: function (params) { 
       this.label = params.label 
       this.id = params.id 
       this.hasError = params.hasError 
       this.formControl = ko.pureComputed(function() { 
        return (this.hasError()) ? "form-group has-error" : "form-group"; 
       }, this); 
      }, 
      template: 
       '<div data-bind="css: formControl">\ 
       <label class="control-label" \ 
       data-bind ="attr: {for: id}"> \ 
        <span data-bind="text: label"></span>:</label>\ 
        <div class="input-group date"\ 
        data-bind= "attr: {id: id}" >\ 
         <input type="text" class="form-control" />\ 
         <span class="input-group-addon">\ 
           <span class="glyphicon glyphicon-calendar"></span>\ 
         </span>\ 
        </div>\ 
       </div>' 
     }); 

我將HTML更改爲。

<datetime-picker 
             params="label: 'Early Pickup', 
             id: 'earlyPickup', 
             hasError: ErlstPickupHasErrors"> 
             </datetime-picker> 

不幸的是我日期時間選取不再實例化。我假設,因爲我現在正在使用一個組件,我不能直接引用id?當調用日期時間選擇器$('#earlyPickup').datetimepicker(它不知道earlyPickup在這一點上是什麼?

+0

你如何安裝機械手的元素?如果您在加載時立即執行該操作,則可能會發生這種情況,因此您可能會錯過該ID。 –

+1

你也可以使用'datetimepicker'控件的綁定處理程序,並在你擁有該控件的地方使用它 – gkb

回答

1

問題是組件是異步加載的。當您嘗試附加日期選擇器時,您的組件可能會或可能不會在頁面上呈現。另外,爲了使拾取器工作,需要需要。所以你必須等到組件被渲染,並且綁定被應用。

解決這個問題的方法之一是添加一個preprocessNode處理程序來檢查遍歷的節點。然後,您可以確定節點是否需要將拾取器連接到它。然後,如果設置了ID,則附加選取器,否則重試一些次數。

例如,

ko.components.register('form-input', { 
    viewModel: function(params) { 
    this.inputValue = params.value; 
    this.label = params.label; 
    this.id = params.id; 
    }, 
    template: '<div class ="form-group">\ 
    <label class="control-label col-sm-2" \ 
      data-bind ="attr: {for: id}"> \ 
     <span data-bind="text: label"></span>:\ 
    </label>\ 
    <div class="col-sm-9">\ 
     <input type="text"\ 
      class="form-control datepicker"\ 
      data-bind="textInput: inputValue, attr: {id: id}"/>\ 
    </div>\ 
    </div>' 
}); 

ko.bindingProvider.instance.preprocessNode = function (node) { 
    if (node.nodeType == 1) { 
    if ($(node).hasClass('datepicker')) { 
     if (node.id) { // an id is required 
     attachDatepicker(node); 
     } else { 
     retryAttachDatepicker(node, 3); 
     } 
    } 
    } 

    function attachDatepicker(node) { 
    $(node).datepicker(); 
    ko.utils.domNodeDisposal.addDisposeCallback(node, function() { 
     $(node).datepicker('destroy'); 
    }); 
    } 

    // would be easier to use a microtask but this is pre 3.4 
    function retryAttachDatepicker(node, tries) { 
    if (tries > 0) { 
     setTimeout(function() { 
     if (node.id) { 
      attachDatepicker(node); 
     } else { 
      retryAttachDatepicker(node, tries - 1) 
     } 
     }, 10); 
    } else { 
     console.warn('unable to attach datepicker to node %o', node); 
    } 
    } 
}; 

fiddle

+0

謝謝,我的兒子也提出了這個解決方案,不過我想我會嘗試使用ko綁定處理程序作爲gkb推薦的,這可能是淘汰賽的方式。 –

+0

啊,你知道嗎,我回答了一個關於datepicker的問題,並在綁定處理程序中使用它。 http://stackoverflow.com/questions/25838821/knockout-js-with-jquery-ui-datepicker-missing-instance-data-for-this-datepick。將它與組件結合起來肯定會更加乾淨。至少在那裏,你可以訪問元素,正如我在那裏提到的那樣,id是datepicker工作的關鍵。 –