2016-12-28 4 views
-1

J'ai fait un petit violon montrant ma question ici http://jsfiddle.net/LkqTU/33025/référence à un ID créé dans un composant à élimination directe

DatePicker fabriqué à l'aide d'un composant ne se déclenche pas

ci-dessous est mon premier post ...

J'utilise le sélecteur bootstrap 3 date et il fonctionne comme suit.

javascript 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> 

.

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

cela fonctionne très bien mais j'ai plusieurs de ces ramasseurs de temps de date donc je tenté de créer un composant à élimination directe.

composant.

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>' 
     }); 

et j'ai changé mon HTML en.

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

Malheureusement, mon sélecteur de date n'est plus instancié. Je suppose que parce que je suis en train d'utiliser un composant, je ne peux pas me référer à id directement? Lorsque vous appelez le sélecteur d'heure de date $('#earlyPickup').datetimepicker(, ne sait-il pas ce que earlyPickup est en ce moment?

+0

Comment êtes-vous le sélecteur à la fixation des éléments? Si vous le faites immédiatement sur le chargement, les chances sont, les identifiants ne seront pas encore appliqués afin que vous puissiez le manquer. –

+1

vous pouvez également utiliser un gestionnaire de liaison pour le contrôle 'datetimepicker' et l'utiliser partout où vous avez ce contrôle – gkb

Répondre

1

Le problème est que les composants sont chargés de manière asynchrone. Vos composants ont peut-être été rendus sur la page au moment où vous essayez de joindre le sélecteur de date. De plus, un identifiant est requis pour que le sélecteur fonctionne. Vous devrez donc attendre que les composants soient rendus et que les liaisons soient appliquées. Une façon de résoudre ce problème consiste à ajouter un gestionnaire preprocessNode pour inspecter les nœuds lorsqu'ils sont traversés. Vous pouvez ensuite déterminer si un noeud doit être associé au sélecteur. Puis attachez le sélecteur si un identifiant est défini, sinon réessayez un certain nombre de fois.

par exemple,

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

merci, mon fils a également suggéré cette solution mais je pense que je vais essayer d'utiliser le gestionnaire de liaison ko comme recommandé par gkb, C'est probablement le moyen le plus efficace de le faire. –

+0

Ah vous savez quoi, j'ai répondu à une question sur le datepicker et l'utiliser dans un gestionnaire de liaison. http://stackoverflow.com/questions/25838821/knockout-js-with-jquery-ui-datepicker-missing-data-data-for-this-datepick. Il sera certainement beaucoup plus propre de combiner cela avec le composant. Au moins là, vous avez accès à l'élément et comme je le mentionne ici, l'identifiant est la clé du fonctionnement du datpicker. –