2015-08-04 19 views
5

Sto creando direttive per una libreria che i clienti possono utilizzare. Devo lasciare che i clienti creino i propri modelli per una direttiva e trasmettano il valore di url assoluto di quel modello nelle mie direttive. Una delle mie direttive avrà al suo interno un'altra direttiva personalizzata, e il suo modello verrà calcolato in base al valore di uno degli attributi della direttiva genitore. Ecco un esempio:Passaggio di un attributo di direttiva padre a un attributo di direttiva figlio

<parent-dir menu-template="this.html" item-template="that.html"></parent-dir> 

Ho un modello per questa direttiva che assomiglia a questo:

<ul style="list: none" ng-repeat="item in menu"> 
    <child-dir template="{{itemTemplate}}"></child-dir> 
</ul> 

mie direttive simile a questa:

angular.module('myApp') 
.directive('parentDir', function() {   
    return { 
     restrict: 'E', 
     scope: { 
      menuTemplate: '@', 
      itemTemplate: '@', 
      menuType: '@', 
      menuName: '@', 
      menuId: '@', 
     }, 
     templateUrl: function (element, attrs) { 
      alert('Scope: ' + attrs.menuTemplate); 
      return attrs.menuTemplate; 
     }, 
     controller: function ($scope, $element, $attrs) { 
      $scope.defaultSubmit = false; 
      alert('Menu: '+$attrs.menuTemplate); 
      alert('Item: ' + $attrs.itemTemplate); 
      $scope.itemTemplate = $attrs.itemTemplate; 
      if ($attrs.$attr.hasOwnProperty('defaultSubmit')) { 
       alert('It does'); 
       $scope.defaultSubmit = true; 
      }    
     } 
    }; 
}) 
.directive('childDir', function() { 
    return { 
     restrict: 'E', 
     require: '^parentDir', 
     templateUrl: function (element, attrs) { 
      alert('Item Template: ' + attrs.template); 
      return attrs.template; 
     }, 
     controller: function ($scope, $element, $attrs) {     
      $scope.job; 
      alert('Under job: ' + $scope.itemTemplate); 
     } 
    }; 
}); 

io non sto mostrando tutti il codice ma questo è il pezzo principale del mio problema. Quando lo eseguo, continuo a diventare indefinito per il modello sul childDir.

Qual è la migliore procedura per perpetuare il valore di itemTemplate da parentDir in modo che childDir possa utilizzarlo come modello?

risposta

4

Il motivo per cui si verificano problemi è perché la funzione che genera lo templateUrl è in esecuzione prima che un scope sia stato assegnato alla direttiva, operazione che deve essere eseguita prima che i dati interpolati possano essere sostituiti.

In altre parole: nel punto in cui viene eseguita la funzione templateUrl, il valore dell'attributo template è ancora "{{itemTemplate}}". Ciò resterà valido fino all'esecuzione della funzione di collegamento della direttiva (preLink).

Ho creato un plunker per dimostrare il punto here. Assicurati di aprire la console. Vedrai che templateUrl viene eseguito prima delle funzioni di collegamento padre e figlio.

Quindi cosa fai invece?

Fortunatamente, angolare offre un servizio $templateRequest che permette di richiedere il modello nello stesso modo sarebbe utilizzando templateUrl (si utilizza anche il $templateCache che è a portata di mano).

mettere questo codice nel tuo funzione di collegamento:

$templateRequest(attrs.template) 
    .then(function (tplString){ 
     // compile the template then link the result with the scope. 
     contents = $compile(tplString)(scope); 
     // Insert the compiled, linked element into the DOM 
     elem.append(contents); 
    }) 

È possibile rimuovere qualsiasi riferimento al template nell'oggetto definizione di direttiva, e ciò in modo sicuro eseguire una volta che l'attributo è stato interpolato.

+1

Grazie per l'aiuto! L'ho provato in questo modo e funziona! Inoltre, ho provato ad usare template e ho passato una funzione che avrebbe aggiunto l'attributo sulla direttiva child impostando template su una stringa e aggiungendo in tal modo attrs.itemTemplate. –

+1

Caso d'uso leggermente diverso ma lo stesso problema di base. Questa risposta ha funzionato. @ Michael se sei in giro pensi che valga la pena accettare questa risposta per aiutare altre persone come me, indicando che questa è una buona risposta? – sifriday

Problemi correlati