指令与分离范围与AngularJS
我读过一些类似的回答我的问题控制器通信,如this one虽然不能将其翻译成我自己的要求 - 来自缺乏了解......指令与分离范围与AngularJS
我有一个控制器:
appControllers.controller('TransactionsCtrl', ['$scope', 'InfiniteScrollingDataService', function ($scope, dataService) {
// setup our scope properties
$scope.$root.title = 'Transactions';
var urlQuery = {
skip: 0,
take: 25,
search: '',
order: 'DateTimeCreated',
orderBy: 'desc',
transactionTypeID: null,
transactionStatusID: null
};
var apiUrl = 'api/transactions';
$scope.transactions = new dataService(apiUrl, urlQuery);
$scope.Filter = function (senderParent, type, id) {
$scope.FilterApplied = true;
console.log('filter in controller: ' + senderParent + ' ' + type + ' ' + id);
}
}]);
而且我有一个指令:
appDirectives.directive('bootstrapListItems', ['$rootScope', function ($rootScope) {
return {
restrict: 'A',
templateUrl: 'bootstrapDropDownItems.html',
link: function (scope, element, attrs) {
scope.type = attrs.useGlobaljsonObject;
scope.parentElement = attrs.id;
scope.items = [];
var obj = $rootScope.globalJSON[scope.type];
for (o in obj) {
scope.items.push({ key: o, value: obj[o] })
}
}
}
}]);
而对于我的指令模板:
<script type="text/ng-template" id="bootstrapDropDownItems.html">
<li class="active"><a href="#" class="lnkFilterList">- Any -</a></li>
<li ng-repeat="item in items">
<a href="#" class="lnkFilterList" ng-click="Filter(parentElement, type, item.key)">{{item.value}}</a>
</li>
</script>
如果我不隔离指令的作用域,那么控制器被调用正确,我看到控制台注销我的参数。
但是,我(想)我需要隔离范围,因为该页面上会有这个指令的倍数。
当我添加scope: {}
到我的指令控制器功能不再被调用。
我也尝试将我的ng-click
更改为ng-click="$parent.Filter(.....)"
- 这似乎也没有工作。
任何人都可以请我指出正确的方向吗?
ng-click="$parent.Filter(.....)"
不起作用,因为您在ng-repeat
中创建了一个(非隔离)范围。在这种情况下,你会写
ng-click="$parent.$parent.Filter(.....)"
,但不这样做......
你可以发出在单击事件处理程序的事件,并在控制器中侦听它。
<script type="text/ng-template" id="bootstrapDropDownItems.html">
<li class="active"><a href="#" class="lnkFilterList">- Any -</a></li>
<li ng-repeat="item in items">
<a href="#" class="lnkFilterList" ng-click="onClick(parentElement, type, item.key)">{{item.value}}</a>
</li>
</script>
指令:
appDirectives.directive('bootstrapListItems', ['$rootScope', function ($rootScope) {
return {
restrict: 'A',
templateUrl: 'bootstrapDropDownItems.html',
link: function (scope, element, attrs) {
scope.type = attrs.useGlobaljsonObject;
scope.parentElement = attrs.id;
scope.items = [];
var obj = $rootScope.globalJSON[scope.type];
for (o in obj) {
scope.items.push({ key: o, value: obj[o] })
}
scope.onClick = function(){
// pass an array of original arguments to the event
scope.$emit('someEventName', Array.prototype.slice.call(arguments));
};
}
}
}]);
控制器:
appControllers.controller('TransactionsCtrl', ['$scope', 'InfiniteScrollingDataService', function ($scope, dataService) {
// setup our scope properties
$scope.$root.title = 'Transactions';
var urlQuery = {
skip: 0,
take: 25,
search: '',
order: 'DateTimeCreated',
orderBy: 'desc',
transactionTypeID: null,
transactionStatusID: null
};
var apiUrl = 'api/transactions';
$scope.transactions = new dataService(apiUrl, urlQuery);
$scope.$on('someEventName', function(e, args){
// call the $scope.Filter function with the passed array of arguments
$scope.Filter.apply(null, args);
});
$scope.Filter = function (senderParent, type, id) {
$scope.FilterApplied = true;
console.log('filter in controller: ' + senderParent + ' ' + type + ' ' + id);
}
}]);
嗨。我喜欢这个解决方案,因为它可以让我在指令中更改所选项目的某些课程信息。然而,我几乎复制/粘贴这个,出于某种原因,我的参数在我的$ scope中是空的。$ on('filterSelected',function(e,args){...'并且都是undefined在我的$ scope.Filter函数。任何想法,我可能会出错? – Darren
其实 - 如果我改变'Array.prototype.slice(参数)'只是'参数'它一切按规定工作。不知道为什么(不使用片之前......) – Darren
任何想法为什么Array.prototype.slice(arguments)返回一个空数组? – Darren
拥有在多个地方使用,并不意味着你不能使用共享范围的指令。如果指令总是显示相同的状态(因此每个继承和操作控制器的相同属性),或者它们每个都打算显示它们自己的状态版本(因此被隔离),那么这个决定归结为。因为你在$ scope.FilterApplied中设置了一个控制器级变量,我假设你只是想在页面上重复相同的控件?如果是这样,你可以坚持一个继承范围。
如果不是,每个指令都需要它自己的功能,您最好将Filter代码移动到指令和控制器都注入的服务中,以便实用程序功能可以共享,但设置和过滤器的状态是根据范围而不是共享的。
最终取决于你如何使用它。
我假设(由于缺乏这方面的知识),我将需要一个隔离范围。网页上会有几个使用此指令的元素。每个显示列表中的不同项目。另外,当选择过滤器的项目时,我需要设置所选项目的类别。在这种情况下,仍然不确定是否需要隔离作用域。 – Darren
继承作用域将简单地允许它继承其父代的作用域,而不是创建自己的作用域。如果您显示的是同一个列表,并且它由控制器中的对象/属性确定,那么继承范围是最简单的路径。指令的每个实例都可以包含属性,以更改它们显示的列表的哪一部分。只有在操作和封装自己的数据副本时,才需要隔离范围。否则,每次更改控制器列表时,它们都会一起更改。这只是一个原型链。 –
啊,好的。现在它变得更清晰了。在这些列表中没有双向绑定或类似的东西。这只是告诉控制器从应用此过滤器的web api获取一些数据。我喜欢kamilkp给予的解决方案,因为我可以在被选中的项目的指令内做更多的事情 - 更改类等等。谢谢你澄清 – Darren
这将有助于解决您的问题http://stackoverflow.com/questions/15991137/calling-method-of-parent-controller-from-a-directive-in-angularjs/15991525#15991525 –