2016-01-26 16 views
5

Sembra che mi confonda con obiettivi isolati nelle direttive e spero che tu possa darmi una mano.AngularJS - Direttive di avvolgimento

Ho provato a racchiudere una parte di codice (che contiene alcune direttive personalizzate) in una nuova direttiva per ridurre la duplicazione del codice. Ovviamente avevo bisogno di dare alcuni attributi come ng-model nella mia nuova direttiva come parametro per rendere la direttiva riutilizzabile. ng-model non piace le espressioni però (ho provato ng-model="{{myVariableWhichContainsDesiredNgModelString}}" all'inizio) e quindi mi sono ritrovato in questo articolo: AngularJS - Create a directive that uses ng-model.

Mentre la risposta accettata sembra funzionare per una semplice configurazione, ho modificato il plunker dalla risposta accettata per verificare se avrebbe funzionato anche con le direttive nidificate: (nella mia app ho bisogno di racchiudere le direttive di una terza parte -library che non posso modificare) Plunker. Nel mio codice ogni direttiva sembra generare il proprio ambito e il collegamento bidirezionale utilizzando = nella definizione dell'ambito non sembra funzionare come desiderato.

EDIT: Dal momento che non era chiaro che cosa sto chiedendo ho modificato il Plunker sopra e vi riformulare la domanda: Nel Plunker ho tre ingressi campi che dovrebbero legarsi allo stesso modello-valore. Funziona inizialmente, ma non appena modifico il terzo campo di input genera la sua variabile nel suo ambito isolato invece di aggiornare il valore iniziale. Ovviamente il terzo campo di input si riferisce alla nuova variabile da quel punto in poi. Come posso evitare questo comportamento e mantenere l'input collegato a $scope.model.name?

Osservazione: la rimozione del isolato-scope-direttiva dal modello fa funzionare tutto come previsto ...

template: '<div><my-input ng-model="myDirectiveVar"></my-input></div>', 

invece di

template: '<div><my-isolated-scope-directive><my-input ng-model="myDirectiveVar"></my-input></my-isolated-scope-directive></div>', 

Plunker

HTML:

<!-- this binds to the model which i would like all my inputs to bind to.--> 
<input ng-model="name"> 

<!-- Example 1: This seems to generate a new modelvalue in the isolated-scope directive. Can I avoid this without modifying that directive?--> 
<my-isolated-scope-directive><my-input ng-model="name"></my-input></my-isolated-scope-directive> 

<!-- Example 2: This is what i would like my code to look like in the end: One directive which uses the code-snippet of Example 1 as template and passes some parameters into that template.--> 
<my-wrapper-directive my-directive-var="name"></my-wrapper-directive> 

direttive:

my-input contiene una modifica input-field:

app.directive('myInput', function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     require: 'ngModel', 
     template: '<input class="some">', 
     link: function($scope, elem, attr, ctrl) { 
      console.debug($scope); 
     } 
    }; 
}) 

my-isolated-scope-directive è un segnaposto-direttiva con il proprio ambito isolato per simulare il comportamento di direttive nidificate:

.directive('myIsolatedScopeDirective', function() { 
    return { 
     restrict: 'E', 
     transclude: true, 
     replace: true, 
     scope: { 
      something: '=' 
     }, 
     template: '<div ng-transclude></div>', 
     link: function($scope, elem, attr, ctrl) { 
      console.debug($scope); 
     } 
    }; 
}) 

my-wrapper-directive racchiude entrambe le direttive precedenti e accetta un parametro che dovrebbe essere utilizzato come valore ng-modello del campo di input:

.directive('myWrapperDirective', function() { 
    return { 
     restrict: 'E', 
     transclude: false, 
     replace: true, 
     scope: { 
      myDirectiveVar: '=' 
     }, 
     template: '<div><my-isolated-scope-directive><my-input ng-model="myDirectiveVar"></my-input></my-isolated-scope-directive></div>', 
     link: function($scope, elem, attr, ctrl) { 
      console.debug($scope); 
     } 
    }; 
}); 

Eventuali suggerimenti e suggerimenti su quello che mi manca sono apprezzati. Posso forse collegare in qualche modo ng-model a un'istanza di servizio senza rendere la mia direttiva dipendente da quel servizio?

+0

Che cosa effettivamente non funziona? Se vuoi dire che l'aggiornamento del 2 ° e del 3 ° campo non viene aggiornato 1 - sembra il solito problema con i punti. –

+0

A quanto pare stavo semplificando troppo nel Plunker. Ho aggiornato il Plunker qui: http://plnkr.co/edit/0soT4nLkFqob4lHxyJ1Y?p=preview e spero che il problema sia più chiaro ora. Il secondo campo funziona come previsto, tuttavia il terzo campo genera il proprio campo di applicazione non appena lo si modifica. –

+0

Si sta verificando questo problema probabilmente, perché non si sta utilizzando il "." punto. Crea un oggetto e usa le sue proprietà: myobject.valueToBind – eesdil

risposta

2

Non vorrei farlo in quanto è la notazione precedente che utilizza gli ambiti ...Vorrei usare controllerAs e bindToController

script:

var app = angular.module('plunker', []); 

app.controller('MainCtrl', function() { 
    this.model = { name: 'World' }; 
    this.name = "Felipe"; 
}); 

app.directive('myInput', function() { 
    return { 
    restrict: 'E', 
    replace: true, 
    // controllerAs: 'app', 
    require: 'ngModel', 
    template: '<input class="some">', 
    controller: function(){ 

    } 
    }; 
}) 
.directive('myIsolatedScopeDirective', function() { 
    return { 
    restrict: 'E', 
    transclude: true, 
    controllerAs: 'app1', 
    bindToController: { 
     something: '=' 
    }, 
    template: '<div ng-transclude></div>', 
    controller: function(){ 

    } 
    }; 
}) 
.directive('myWrapperDirective', function() { 
    return { 
    restrict: 'E', 
    transclude: false, 
    controllerAs: 'app2', 
    bindToController: { 
     myDirectiveVar: '=' 
    }, 
    template: '<div><my-isolated-scope-directive>'+ 
     '<my-input ng-model="app2.myDirectiveVar"></my-input>'+ 
     '</my-isolated-scope-directive></div>', 
    controller: function(){ 

    } 

    }; 
}); 

indice:

<!doctype html> 
<html ng-app="plunker" > 
<head> 
    <meta charset="utf-8"> 
    <title>AngularJS Plunker</title> 
    <link rel="stylesheet" href="style.css"> 
    <script>document.write("<base href=\"" + document.location + "\" />");</script> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script> 
    <script src="app.js"></script> 
</head> 
<body ng-controller="MainCtrl as main"> 
    This scope value 
    <input ng-model="main.model.name"> 
    <my-isolated-scope-directive> 
    <my-input ng-model="main.model.name"></my-input> 
    </my-isolated-scope-directive> 
    <my-wrapper-directive my-directive-var="main.model.name"> 
    </my-wrapper-directive> 
</body> 
</html> 

Vedere il plunker: http://plnkr.co/edit/VD0wXO1jivQc3JvfQFTh?p=preview

UPDATE Sì, buon punto, quindi, se si desidera usa controllerAs, hai bisogno di angolare 1.2 come minimo, per bindToController hai bisogno di angolare 1.3

+0

Grazie mille! Ciò richiede in realtà 1,4,8 btw angolari, quindi se qualcuno si imbatte in problemi durante l'utilizzo di questo, prova ad aggiornare la versione angolare. –

+0

un'altra domanda per la sintassi ControllerAs: vai al tuo plunker e usa la direttiva my-wrapper due volte con variabili diverse. 'My-directive-var' della seconda direttiva sovrascriverà il primo. Perché il controller-scope è condiviso e posso renderlo nuovamente isolato per direttiva? –

Problemi correlati