我有一个包含很多本质上是重复代码的模板。我想使用一个指令包括一个局部模板,我可以为每个重复代码的“块”进行操作。
该模板当前看起来像这样:
<div class="column book">
<div class="header">
<input type="text" id="book_query" ng-model="book_query.name" />
</div>
<div class="content">
<div class="row" ng-repeat="book in books | filter:book_query">
{{book.name}}
</div>
</div>
</div>
....
<div class="column game">
<div class="header">
<input type="text" id="game_query" ng-model="game_query.name" />
</div>
<div class="content">
<div class="row" ng-repeat="game in games | filter:game_query">
{{game.name}}
</div>
</div>
</div>
....
控制器仅获取数据并将其添加到范围,例如
$scope.books = data.books;
$scope.games = data.games;
我开始做的是使用带有参数(例如书,游戏等)的指令,这样我便知道要使用哪种模型。我的问题是如何使用参数访问模板中的模型?目前,该指令本身非常简单:
<div item-column item="book"></div>
<div item-column item="game"></div>
app.directive('itemColumn', function() {
return {
scope: {
item: '@'
},
replace: true,
templateUrl: 'item_column.html'
};
});
我希望在item_column.html中可以替换item参数,该参数可以很好地显示arg的值,但不能替换模型中使用“ book”或“ game”的位置,例如
<div class="column {{item}}">
<div class="header">
<input type="text" id="{{item}}_query" ng-model="{{item}}_query.name" />
</div>
<div class="content">
<div class="row" ng-repeat="item in ??? | filter:{{item}}_query">
{{item.name}}
</div>
</div>
</div>
有人可以告诉我最好的方法吗?我毫不怀疑我会采取完全错误的方式!
编辑:上面的原始问题现在可以使用JoseM的下面的答案完全解决。一个未解决的问题是每个元素上的单击功能不再从隔离范围内触发父范围。
我的控制器的布局如下:
app.controller('ItemsCtrl', ['$scope', '$http', 'CONFIG', function($scope, $http, CONFIG) {
var items = ['books', 'games'];
items.forEach(function(item) {
$scope[item] = [];
$scope['selected_'+item] = null;
})
$scope.getItem = function(item) {
$http.get('?action=get_item&id='+item.id+'&type='+item.type)
.success(function(data) {
// update model
})
.error(function(data, status) {
// do something
});
}
}]);
单击视图中的项目时,将无法再访问$ scope.getItem,在实现JoseM的答案后,其外观类似于以下内容:
<div class="row" ng-repeat="item in array | filter:query">
<div class="text" ng-click="getItem(item)">
{{item.name}}
</div>
</div>
是否有一种简单的方法可以使父作用域函数在隔离的作用域内可用?还是这些功能有更好的地方?道歉(我的感觉)是最基本的问题-我仍在努力使Angular脱颖而出!
一种实现所需功能的方法是,在指令中使用子范围,然后使用对父范围值的监视来对父范围变量进行自己的“链接”。
在您的指令中:
app.directive('itemColumn', function() {
return {
scope: true,
templateUrl: 'item_column.html',
link: function(scope,elem,attrs) {
var varName = scope.varName = attrs.item;
var parScope = scope.$parent;
parScope.$watch(varName + 's', function(newVal){
scope.theArray = newVal;
});
parScope.$watch(varName + '_query', function(newVal){
scope.theQuery = newVal;
});
}
};
});
在您的模板中:
<div class="column {{varName}}">
<div class="header">
<input type="text" ng-attr-id="{{varName}}_query" ng-model="theQuery.name" />
</div>
<div class="content">
<div class="row" ng-repeat="item in theArray | filter:theQuery">
{{item.name}}
</div>
</div>
</div>
如果要使用隔离范围,可以这样做,但是如果使用与上述相同的属性,则必须至少提供3个属性。我个人认为,使用隔离范围是一种更好的方法。参见下面的隔离版本如何更简单:
指令的隔离版本
app.directive('itemColumn2', function() {
return {
scope: {
label: '@',
array: '=',
query: '='
},
templateUrl: 'item_column2.html'
};
});
模板的隔离版本
<div class="column {{label}}">
<div class="header">
<input type="text" ng-attr-id="{{label}}_query" ng-model="query.name" />
</div>
<div class="content">
<div class="row" ng-repeat="item in array | filter:query">
{{item.name}}
</div>
</div>
</div>
用法
<div item-column2 label="book" array="books" query="book_query"></div>
<div item-column2 label="game" array="games" query="game_query"></div>
最后是一个示例示例:http ://plnkr.co/edit/OyEHR4ZhzYKvs4jeDfjD?p=preview
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句