Angular ng-click Not Working Directive

Plunker

I have an external controller that contains a directive inside my view. The directive receives a list of process points and creates links where you can select them. It correctly configures HTML in the link function, but ng-click link actions do not work.

Any ideas? :)

Code for Non-Plunkering

HTML

<!DOCTYPE html> <html> <head><link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet"> <script src="http://code.jquery.com/jquery-2.0.3.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script> <script src="script.js"></script> </head> <body ng-app="app"> <div ng-controller="widget"> <process stages="production" at="productionAt"></process> </div> </body> </html> 

Js

 angular.module('app', ['app.directives', 'app.controllers']); angular.module('app.controllers', []) .controller('widget', function($scope) { var selectStage = function () { alert(this.label + " selected."); $scope.processAt = this; } $scope.production = [ {label: "Starting", select: selectStage} , {label: "Fermenting", select: selectStage} , {label: "Pouring", select: selectStage} , {label: "Beer!", select: selectStage} ]; $scope.productionAt = $scope.production[0]; }); angular.module('app.directives', []) .directive('process', function() { return { restrict: 'E' , replace: true , template: '<ol class="nav nav-pills"></ol>' , scope: { stages: "=" , at: "=" } , link: function postLink(scope, element, attrs) { for (var i = 0; i < scope.stages.length; i++) { var $stage = $('<li ng-click="stages['+i+'].select()"><a>'+scope.stages[i].label+'</a></li>'); if (scope.at == scope.stages[i]) { $stage.addClass('active'); } $(element).append($stage); } } } }); 
+4
source share
2 answers

To make the ng-click directive, it must first be processed ('compiled') by the angular infrastructure, so instead of manually creating li elements in your directive, about which angular does not have that they exist, you can use ng-repeat in the directive template as follows ( no need to manually create DOM elements):

 angular.module('app.directives', []) .directive('process', function() { return { restrict: 'E' , replace: true , template: '<ol class="nav nav-pills"><li ng-class="{active: stage==at}" ng-click="stage.select()" ng-repeat="stage in stages"><a>{{stage.label}}</a></li></ol>' , scope: { stages: "=" , at: "=" } } }); 

Modified plunker: http://plnkr.co/edit/SW1Ph0nIjVYW3UzixtBx?p=preview

I think this is the most elegant solution. Of course, you can move the template to an eternal file and refer to it through templateUrl .

Alternatively, you can use the $compile service for an element after manually adding li elements, but this seems like a hack.

+8
source

Working URL http://plnkr.co/edit/3zuDuQDjhA5UY5nLD09Z?p=preview

Please make a change to the url directive below.

 angular.module('app.directives', []) .directive('process', function($compile) { return { restrict: 'E' , replace: true , template: '<ol class="nav nav-pills"></ol>' , scope: { stages: "=" , at: "=" } , link: function postLink(scope, element, attrs) { for (var i = 0; i < scope.stages.length; i++) { var $stage = $('<li ng-click="stages['+i+'].select()"><a>'+scope.stages[i].label+'</a></li>'); if (scope.at == scope.stages[i]) { $stage.addClass('active'); } $(element).append($stage); $compile($(element))(scope); } } } }); 

I entered $ complie and added one line $ compile ($ (element)) (scope);

+2
source

Source: https://habr.com/ru/post/1495076/


All Articles