ng-click non funziona all’interno del modello di una direttiva

Noob angular qui. Sto creando una direttiva per visualizzare ricorsivamente un albero di domande e domande secondarie. Sto usando un collegamento nel modello che chiama una funzione all’interno dell’ambito. Per qualche ragione, non chiama il metodo editQuestion() .

Ecco il codice e il violino http://jsfiddle.net/madhums/n9KNv/

HTML:

 

Javascript:

 var app = angular.module('myApp', []); function FormCtrl ($scope) { $scope.editQuestion = function (question) { alert('abc'); }; $scope.survey = { // ... } } app.directive('questions', function($compile) { var tpl = '
    ' + ' <li ng-repeat="question in value | filter:search"' + ' ' + ' {{ question.name }}' + ' ' + ' ({{ question.type }})' + ' remove' + ' edit' + ' ' + ' ' + '
'; return { restrict: 'E', terminal: true, scope: { value: '=' }, template: tpl, link: function(scope, element, attrs) { $compile(element.contents())(scope.$new()); } }; }); app.directive('choices', function($compile) { var tpl = '
    '+ '
  • ' + ' {{ choice.name }}' + ' ' + ' ({{ choice.questions.length }} questions)' + ' ' + '' + ' ' + ' +' + ' ' + '' + ' ' '
  • ' + '
'; return { restrict: 'E', terminal: true, scope: { value: '=' }, template: tpl, link: function(scope, element, attrs) { $compile(element.contents())(scope.$new()); } }; });

Qualsiasi aiuto nella comprensione di ciò sarebbe apprezzato.

Hai un problema di ambito. Poiché hai utilizzato l’ambito isolato nella tua direttiva con scope: { value: '=' } , non ha più accesso all’ambito del controller che ha editQuestion .

Devi passare a editQuestion insieme editQuestion della tua direttiva in modo che sappia come chiamarlo. Questo è in genere piuttosto semplice, ma a causa della struttura direttiva infinitamente ricorsiva in cui le scelte possono includere domande, diventa un po ‘più complicato. Ecco un violino funzionante:

http://jsfiddle.net/n9KNv/14/

L’HTML ora include un riferimento a editQuestion :

 

E la tua direttiva domande ora si aspetta un attributo onEdit nel suo ambito:

 app.directive('questions', function($compile) { var tpl = '
    ' + '
  1. ' + ' {{ question.name }}' + ' ' + ' ({{ question.type }})' + ' edit' + ' ' + '
  2. ' + '
'; return { restrict: 'E', terminal: true, scope: { value: '=', onEdit: '&' }, template: tpl, link: function(scope, element, attrs) { $compile(element.contents())(scope.$new()); } }; }); app.directive('choices', function($compile) { var tpl = '
    '+ '
  • ' + ' {{ choice.name }}' + ' ' + ' ({{ choice.questions.length }} questions)' + ' ' + '' + ' ' '
  • ' + '
'; return { restrict: 'E', terminal: true, scope: { value: '=', onEdit: '&' }, template: tpl, link: function(scope, element, attrs) { $compile(element.contents())(scope.$new()); } }; });

Nota come stiamo indirizzando la question nel ng-click . Questo è il modo in cui si indirizzano gli argomenti nelle funzioni di callback. Inoltre, notiamo come nella on-edit stiamo passando alla direttiva delle choices , stiamo subQuestion mira subQuestion . Questo perché la question è già riservata all’interno di ngRepeat , quindi è necessario distinguere tra i due.

Questo è stato probabilmente il concetto più difficile per me per imparare in Angular finora. Una volta compreso come funziona lo scope tra controller, direttive e altre direttive, il mondo di Angular è tuo. 🙂

Questo è un problema di ambito. Il comando ng-click della direttiva chiama i metodi editQuestion e removeQuestion dell’ambito corrente, che non esistono nell’ambito della direttiva, poiché sono definiti nel modulo che include la direttiva (cioè l’ambito genitore).

Si vuole stabilire un legame tra la direttiva e il genitore, quindi quando la direttiva chiama la funzione ngClick, si triggers sul modulo che ospita la direttiva.

È ansible definire i metodi nella direttiva stessa o impostare l’associazione tramite la sezione dell’ambito dell’object di definizione della direttiva

Ecco un plunker che illustra l’triggerszione degli eventi ng-clic su diversi ambiti (output per console)

http://plnkr.co/edit/9XfXCpU6lhUOqD6nbVuQ?p=preview

La risposta di Langdon del 10 maggio 13 è corretta. A scopo dimostrativo, ho semplificato il codice del violino di Langdon e l’ho portato da 148 linee angolari a 23 linee angolari.
Ho anche aggiunto funzionalità che consentono di passare un valore di parametro come object MouseEvent tramite il metodo di chiamata della funzione e recuperare tale valore nella funzione.

Ecco il JSFIDDLE seguito dal codice e dai crediti, dovrebbe essere molto facile da seguire.

http://jsfiddle.net/BeyondLogical/evjzoo30/

–Html–

 

–AngularJS–

 var app = angular.module('myApp', []); function FormCtrl ($scope) { $scope.editQuestion = function (ev,question) { //ev returns a MouseEvent object alert("ev: " + ev); //this is how you get the 'data' attribute set in the span tag below alert("ev-data: " + ev.target.attributes.data.value); }; } app.directive('questions', function($compile) { var tpl = 'Click Me'; return { restrict: 'E', terminal: true, scope: { onEdit: '&' }, template: tpl, link: function(scope, element, attrs) { $compile(element.contents())(scope.$new()); } }; }); 

Crediti a,
Langdon – ng-click non funziona all’interno del modello di una direttiva

Mark Rajcok – AngularJS riceve $ event da una direttiva (Langdon riceve anche un aiuto per porre la domanda Mark Answers)

PavanAsTechie – Accesso al valore dell’attributo all’interno della funzione di controllo non direttiva e Pavan’s JSFIDDLE – http://jsfiddle.net/brettdewoody/FAeJq/ (in particolare la seguente riga di codice di Pavan): alert(obj.target.attributes.data.value);

Per chiunque si avvicini a questo e provi a farlo con un codice che non è in esecuzione nella direttiva , verifica che non stai utilizzando l’opzione sostituisci .

Per esempio:

 angular.module('app').directive('myDirective', function () { return { template: '
', scope: { options: "=" }, replace: true, //<---- Change this to false restrict: 'E', controller: function ($scope) { $scope.clicked = function(){ console.log("Clicked"); } } }; }