2013-08-07 16 views
8

Sono in procinto di creare alcune direttive riutilizzabili per i controlli comuni nella nostra applicazione.Come creare direttive AngularJs riutilizzabili che copiano le direttive esistenti

Per esempio abbiamo un elemento di cattura-it di HTML per le caselle di testo quantità

<div class='amount'> 
    <input type='text' ng-model='dollars'/> 
</div> 

Da lì ho iniziato a creare il mio direttiva:

app.directive("amount", function(){ 
    return { 
     restrict: "E", 
     template: "<div class='amount'><input type='text'/></div>", 
     replace: true 
    } 
}); 

che rende il seguente <html/>

<div class="amount ng-pristine ng-valid" ng-model="dollars"> 
    <input type="text"> 
</div> 

Ora lo ng-model è il <div/> che non è quello che voglio, quindi ho bisogno di creare un ambito e collegarlo allo ngModel e le cose sono di nuovo felici.

app.directive("amount", function(){ 
    return { 
     restrict: "E", 
     scope:{ 
      ngModel: "=" 
     }, 
     template: "<div class='amount'><input type='text' ng-model='ngModel'/></div>", 
     replace: true 
    } 
}); 

Tutto funziona, ma consente di dire voglio aggiungere anche in una direttiva ngChange, significa che ho di nuovo bisogno di alterare il mio scope includere ngChange: "="? Come così

app.directive("amount", function(){ 
    return { 
     restrict: "E", 
     scope:{ 
      ngModel: "=", 
      ngChange : "=" 
     }, 
     template: "<div class='amount'><input type='text' ng-model='ngModel'/></div>", 
     replace: true 
    } 
}); 

La questione

ho bisogno di modificare continuamente il campo di applicazione delle direttive per includere un numero infinito di possibili altre direttive che potrebbero richiedere? Oppure esiste un modo per copiare le direttive sull'elemento <amount/> non su <div/> ma su <input/>

E.g.

<amount my-awesome-directive="" ng-disabled="form.$invalid" ng-model="dollarsAndCents" ng-click="aClick()" ng-show="shouldShow()"/> 

si trasforma in

<div class="amount"> 
    <input my-awesome-directive="" type="text" ng-disabled="form.$invalid" ng-click="aClick()" ng-show="shouldShow()" ng-model="dollarsAndCents"/> 
</div> 

può qualcosa essere fatto durante il pre/post di compilazione per copiarli sopra o sto andando su questo tutto sbagliato?

Aggiornamento

sono stato in grado di ottenere qualcosa di lavoro tramite semplice loop su tutti gli attributi e utilizzando il servizio $compile(). Funziona, ma è corretto?

app.directive("amount", function ($compile) { 
    return { 
     restrict: "E", 
     template: "<div class='amount'><input type='text' /></div>", 
     replace: true, 
     compile: function compile(tElement, tAttrs) { 
      return function (scope, iElement, iAttrs) { 
       var attributes = $(iElement).prop("attributes"); 
       var $input = $(iElement).find("input"); 
       $.each(attributes, function() { //loop over all attributes and copy them to the <input/> 
        if (this.name !== "class") { 
         $input.attr(this.name, this.value); 
        } 
       }); 
       $compile($input)(scope); //compile the input 
      }; 
     } 
    }; 
}); 

Dato il seguente <html/> se si aggiunge una direttiva al <amount/> esso viene copiato giù al <input/>

<div ng-app="app"> 
     <amount ng-model="dollars" ng-change="changed = 'I Changed!!!'" ng-click="clicked= 'I Clicked It!'" name="amount"></amount> 
     <h1>{{dollars}}</h1> 
     <h2>{{changed}}</h2> 
     <h3>{{clicked}}</h3> 
     <input type="button" value="Remove" ng-click="items.splice(items.indexOf(item), 1)"/> 
     <hr/> 
</div> 

updated jsfiddle

+0

Questo è un post più vecchio, ma hai trovato un modo alternativo diverso dalla copia degli attributi e dalla compilazione? –

+0

Un approccio diverso qui: http://stackoverflow.com/a/42319665/913845 –

risposta

-1

Bind un controller e iniettare $scope per facilità.

.controller('Amount', ['$scope', function($scope) { 
    $scope.myMoney = '2'; 
}]) 

.directive("amount", function(){ 
    restrict: 'EA', 
    replace: true, 
    controller: 'Amount', 
    template: "<div class='amount'><input type='text' ng-model='myMoney'/></div>", 
    //Cleaner to include as URL if the partial is bigger. 
    //templateUrl: '/views/amount.html', 
    link: function(scope, controller) {} 
}); 
+0

Ok, come sarebbe gestita se 'ng-disabled' in una istanza fosse' ctrl.isAmountDisabled() 'e un'altra istanza' ng- disabled' capita di essere 'ctrl2.isSomeThingElseTrue() '(templateurl è l'ideale ma per la domanda è semplice) –

+0

Anche questo non sembra risolvere il problema di avere una direttiva arbitraria su' 'copia giù per' < input super-cool = "" /> '(a meno che manchi qualcosa) –

+0

@Mark Costruisci le tue direttive come moduli che includono i loro controller e li iniettano nella tua app? O stai costruendo direttive e usando i controller di livello app per controllare la logica? –

Problemi correlati