Sté*_*uca 3 angularjs angularjs-directive angularjs-ng-click
我有一个具有局部范围的指令,其中部分包含ng-click.
小提琴就在那里:http://jsfiddle.net/stephanedeluca/QRZFs/13/
不幸的是,由于我将代码移动到指令中,因此ng-click不再触发.
控制器和指令如下:
var app = angular.module('myApp', ['ngSanitize']);
app.directive('plantStages', function ($compile) {
return {
restrict: 'E',
transclude: true,
template: '<figure class="cornStages">\
<p ng-transclude style="color: skyblue"></p>\
<hr/>\
<p ng-bind-html="title"></p>\
<p ng-bind-html="subtitle">{{subtitle}}</p>\
<ul>\
<li ng-repeat="stage in stages" ng-click="changePage(stage)">{{stage}}</li>\
</ul>\
</figure>',
scope: {
stages:"=",
title:'@'
},
link: function (scope, element, attrs, ctrl, transclude) {
if (!attrs.title) scope.title = "Default title";
}
};
});
app.controller('myCtrl', function ($scope, $location, $http) {
$scope.stages = ['floraison', 'montaison'];
$scope.changePage = function (page) {
var url = "corn.page.html#/"+page;
console.log("Change page "+page+" with url "+url);
alert("about to change page as follows: document.location.href = "+url);
};
});
Run Code Online (Sandbox Code Playgroud)
调用它的html如下:
<div ng-controller="myCtrl">
Stages,
<p ng-repeat="stage in stages">{{stage}}</p>
<hr/>
Plant stages
<plant-stages
title="<b>Exploration<br/>du cycle</b>"
subtitle="<em>This is a<br/>sub title</em>"
stages="stages"
>
Inner<br/>directive
</plant-stages>
</div>
Run Code Online (Sandbox Code Playgroud)
任何的想法?
您无法changePage()直接从指令访问控制器范围中定义的内容,因为您的指令具有隔离范围.但是,仍有几种方法可以做到:
选项1:
选项1是最简单的选择.然而,这很像一个解决方法,我不建议广泛使用它.您可以从传递给链接函数的元素获取控制器的作用域并在其中调用changePage:
link: function (scope, element, attrs, ctrl, transclude) {
if (!attrs.title) scope.title = "Default title";
scope.changePage = element.scope().changePage; // <= Get parent scope from element, it will have changePage()
}
Run Code Online (Sandbox Code Playgroud)
选项2:
如果您没有任何涉及在外部控制器中定义范围的逻辑(如您的示例中所示),则可以为您的指令定义内部控制器并在那里执行:
app.directive('plantStages', function ($compile) {
return {
...
controller: ['$scope', function($scope) {
$scope.changePage = function(page) {
var url = "corn.page.html#/"+page;
console.log("Change page "+page+" with url "+url);
alert("about to change page as follows: document.location.href = "+url);
}
}]
};
});
Run Code Online (Sandbox Code Playgroud)
选项3:
如果你想changePage()在不同的指令和控制器中定义重用逻辑,最好的方法是将逻辑移动到可能注入到控制器和指令的某个服务:
app.service('changePageService', function() {
this.changePage = function(page) {
var url = "corn.page.html#/"+page;
console.log("Change page "+page+" with url "+url);
alert("about to change page as follows: document.location.href = "+url);
}
});
app.controller('myCtrl', function ($scope, $location, $http, changePageService) {
...
changePageService.changePage('page');
...
});
app.directive('plantStages', function ($compile) {
...
controller: ['$scope', 'changePageService', function($scope, changePageService) {
$scope.changePage = changePageService.changePage;
}]
...
});
Run Code Online (Sandbox Code Playgroud)
选项4:
您可以传递一段代码,如changePage(page)指令的某些属性的值和指令内部的scope scope属性,'&'这将创建一个函数,该函数将在外部控制器的作用域中执行,并且参数传递给该函数.例:
JavaScript的
app.directive('plantStages', function ($compile) {
return {
restrict: 'E',
transclude: true,
template: '<figure class="cornStages">\
<p ng-transclude style="color: skyblue"></p>\
<hr/>\
<p ng-bind-html="title"></p>\
<p ng-bind-html="subtitle"></p>\
<ul>\
<li ng-repeat="stage in stages" ng-click="changePage({page: stage})">{{stage}}</li>\
</ul>\
</figure>',
scope: {
stages:"=",
title:'@',
changePage:'&'
},
link: function (scope, element, attrs, ctrl, transclude) {
if (!attrs.title) scope.title = "Default title";
}
};
});
Run Code Online (Sandbox Code Playgroud)
HTML
<div ng-controller="myCtrl">
Stages,
<p ng-repeat="stage in stages">{{stage}}</p>
<hr/>
Plant stages
<plant-stages
title="<b>Exploration<br/>du cycle</b>"
subtitle="<em>This is a<br/>sub title</em>"
stages="stages"
change-page="changePage(page)"
>
Inner<br/>directive
</plant-stages>
Run Code Online (Sandbox Code Playgroud)
Plunker: http ://plnkr.co/edit/s4CFI3wxs0SOmZVhUkC4?p =preview