2013-10-21 17 views
8

Sto provando a passare l'URL per il modello tramite una variabile di ambito. L'ambito non cambierà quindi il modello non deve essere aggiornato in base ad esso, ma attualmente la variabile scope è sempre indefinita.Come passare in templateUrl tramite la variabile scope nell'attributo

<div cell-item template="{{col.CellTemplate}}"></div> 

Idealmente la direttiva sarebbe:

.directive("cellItem", ["$compile", '$http', '$templateCache', '$parse', function ($compile, $http, $templateCache, $parse) { 
     return { 
      scope: { 
       template: '@template' 
      }, 
      templateUrl: template // or {{template}} - either way 
     }; 
    }]) 

Questo non funziona comunque. Ho provato molte diverse permutazioni nel realizzare lo stesso concetto, e questo sembra il più vicino, tuttavia non funziona ancora.

Ho anche provato a usare ng-include, ma anche questo non valuta le variabili di scope prima della compilazione. Il valore di CellTemplate proviene da una chiamata al database, quindi è completamente sconosciuto prima della valutazione. Qualsiasi suggerimento per ottenere questo lavoro sarebbe molto apprezzato!

Modifica: Sto usando angular 1.0.8 e non sono in grado di eseguire l'aggiornamento a una versione più recente.

risposta

14

Non sei affatto lontano.

Non è necessario utilizzare un ambito isolato per la direttiva. È possibile passare il TemplateURL in questo modo:

<div cell-item template="col.CellTemplate"></div> 

quindi aggiungere un orologio per rilevare quando il valore cambia modello:

.directive("cellItem", ["$compile", '$http', '$templateCache', '$parse', function ($compile, $http, $templateCache, $parse) { 
     return { 
      restrict: 'A', 
      link: function(scope , element, attrs) { 

       scope.$watch(attrs.template, function (value) { 
       if (value) { 
        loadTemplate(value); 
       } 
       }); 

       function loadTemplate(template) { 
        $http.get(template, { cache: $templateCache }) 
        .success(function(templateContent) { 
         element.replaceWith($compile(templateContent)(scope));     
        });  
       } 
      } 
     } 
    }]); 

Ecco un Plunker di lavoro: http://plnkr.co/edit/n20Sxq?p=preview

+0

Questo funziona sicuramente quando i dati sono predefiniti. Non avevo capito il mio problema è perché sto ricevendo i miei dati da un servizio. Se si impostano i dati in un timeout, si blocca: http://plnkr.co/edit/aLkCRm – John

+0

Mi dispiace per l'equivoco John. Ho modificato la mia risposta con il codice aggiornato e un nuovo Plunker che funziona con il timeout. – tasseKATT

+0

Questo ha fatto il trucco! grazie mille – John

6

Se non lo fai vuoi affrontare la logica di collegamento da solo o vuoi l'ambito isolato, penso che sia più semplice:

.directive("cellItem", ["$compile", '$http', '$templateCache', '$parse', function ($compile, $http, $templateCache, $parse) { 
     return { 
      scope: { 
       template: '@template' 
      }, 
      template: "<div ng-include='template'></div>" 
     }; 
    }]) 

o:

template:"<ng-include src='template'></ng-include>" 
+0

templateUrl è lì per un motivo – caub

1

Si tratta di un vecchio post, ma ho pensato il suo utile se qualcuno atterra in qui per la risposta.

Puoi provare la funzione templateUrl come @caub menzionato in un commento. Lo stesso può essere utilizzato anche per i componenti.

.directive("cellItem", ["$compile", '$http', '$templateCache', '$parse', function ($compile, $http, $templateCache, $parse) { 
    return { 
     templateUrl: function(element, attrs) { 
      return attrs.template || 'someDefaultFallback.html'; 
     } 
    }; 
}]); 

Non abbiamo bisogno di nessuna delle dipendenze iniettate qui. Spero che questo aiuti qualcuno.

Problemi correlati