我有一个指令,该指令具有局部作用域,其中局部包含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);
};
});
调用它的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>
任何的想法?
您不能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()
}
选项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);
}
}]
};
});
选项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;
}]
...
});
选项4:
您可以传递一段代码,例如changePage(page)
伪指令的某些属性的值,以及内部伪指令定义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";
}
};
});
的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>
柱塞: http ://plnkr.co/edit/s4CFI3wxs0SOmZVhUkC4?p=preview
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句