2015-11-21 26 views
16

Sto cercando di ottenere un app che lavora con angolare 1.5.0-beta.2angolare 1.5 metodo di componente TemplateURL + funzione

Per effettuare una 'direttiva' Ho il seguente codice:

myApp.component('gridshow', { 
    bindings: { 
    slides: '=' 
    }, 
    controller: function() { 

    }, 
    controllerAs: 'grid', 
    template: function ($element, $attrs) { 
    // access to $element and $attrs 
    return [ 
     '<div class="slidegrid">', 
     '<div ng-repeat="slide in grid.slides">', 
     '{{slide.image}}', 
     '</div>', 
     '</div>' 
    ].join('') 
    } 
}); 

Mi piace l'idea del modello che restituisce una funzione con accesso a $element e $attrs ma come faccio a combinarlo con un templateUrl?

+3

Non li combinano, si sia utilizzare uno o l'altro. – dfsq

+0

Non sono sorpreso, ma un po 'deluso. Grazie dfsq. – tuvokki

+1

perché deluso. Cosa vorresti fare esattamente con un modello e un modello di url? È come chiedere una scala all'interno di un ascensore ... Sono esclusivi ... –

risposta

19

In 1.5.0-beta.2 templateUrl può essere una funzione invocata dall'iniettore. $element e $attrsare injected in both template and templateUrl functions in component, così come tutte le altre dipendenze.

Questo significa che

... 
    templateUrl: function ($element, $attrs) { 
    // access to $element and $attrs 
    ... 
    return $attrs.uninterpolatedTemplateUrl; 
    } 

può essere fatto, invece.

+1

E come funziona con un modello esterno? Normalmente templateUrl contiene un riferimento al modello. – tuvokki

+0

Esatto. Pertanto, la decisione può essere presa sull'URL del modello basato su ad es. attributi di elemento. Per cosa avevi intenzione di usarlo? Se ci si aspettava di ottenere la risposta del template nella funzione templateUrl, quindi no, è ancora necessario elaborare un modello più avanti nella direttiva (non abbiamo una funzione di collegamento nel componente, ma c'è un controller). – estus

+0

Capisco, estus, e non avevo un vero obiettivo qui. Mi stavo solo chiedendo. – tuvokki

3

@estus soluzione ha funzionato per me fino a quando non ho migliorato i miei script. Uglified ha dato il seguente errore:

Error: [$injector:unpr] Unknown provider: eProvider <- e 

La soluzione che ha funzionato per me è:

['$element', '$attrs', function($element, $attrs) { 
    return $attrs.uninterpolatedTemplateUrl; 
}] 
+3

** Tutte le funzioni ** in Angolare che utilizzano DI devono essere annotate per essere correttamente ridotte. Cioè quasi tutte le funzioni in API angolari, ad eccezione delle funzioni direttive ('link',' template', ecc.). Questo è spesso omesso negli esempi perché si tratta di un'azione predefinita. – estus

6

Ho risolto questo problema seguendo la tecnica. Questo potrebbe aiutarti.

Template

<div data-ng-repeat="field in $ctrl.fields track by $index"> 
    <render-field data-field-type="{{field.type}}"></render-field> 
</div> 

Un componente

/** 
* @ngdoc Component 
* @name app.component.renderField 
* @module app 
* 
* @description 
* A component to render Field by type 
* 
* @author Mohan Singh (gmail::[email protected], skype :: mohan.singh42) 
*/ 
(function() { 
    'use strict'; 

    angular 
    .module('app') 
    .component('renderField', { 
     bindings: { 
     fieldType: '@', 
     }, 
     template: '<div ng-include="$ctrl.templateUrl">', 
     controller: [ 
     function() { 
      var $ctrl = this; 
      $ctrl.$onInit = initialization; 
      $ctrl.$onDestroy = onDestroy; 
      $ctrl.$onChanges = onChanges; 

      /** 
      * public properties 
      */ 
      /** 
      * public methods 
      */ 
      /** 
      * @function 
      * @name initialization 
      * @description 
      * A component's lifeCycle hook which is called after all the controllers on an element have been constructed and had their bindings initialized 
      */ 
      function initialization() { 
      } 

      /** 
      * @function 
      * @name onChanges 
      * @description 
      * A component's lifeCycle hook which is called when bindings are updated. 
      */ 
      function onChanges(bindings) { 
      if(bindings.fieldType && bindings.fieldType.isFirstChange()){ 
       //$ctrl.fieldType['text' | 'textarea' | 'select' | 'radio'] 
       $ctrl.templateUrl = 'partials/fields/'+$ctrl.fieldType+'.html'; 
      } 
      } 
      /** 
      * @function 
      * @name onDestroy 
      * @description 
      * A component's lifeCycle hook which is called when is called on a controller when its containing scope is destroyed. 
      * Usefull to release external resources, watches and event handlers. 
      */ 
      function onDestroy() { } 
     }] 
    }); 
})(); 
+1

Mate, quella soluzione è eccellente! Ho risolto con percorsi diversi, con il valore configurabile codificato nell'HTML (poiché l'ambito non è disponibile per il binding). La tua soluzione è molto più bella. Vorrei poter votare ancora di più! –

+0

@DanielMackay felice di aiutarti. –

Problemi correlati