【发布时间】:2013-08-17 14:10:59
【问题描述】:
关于如何在 ngRepeat 指令中实现项目删除有很多问题,据我所知,它归结为使用 ngClick 并触发一些删除函数,传递它的项目的 $索引。
但是,我在任何地方都找不到我有多个 ngRepeats 的示例:
<div ng-controller="MyController">
<div ng-repeat="email in user.emails">
{{ email }} <a href>Remove</a>
</div>
<div ng-repeat="phone in user.phones">
{{ phone }} <a href>Remove</a>
</div>
</div>
为此,我需要创建 $scope.removePhone 和 $scope.removeEmail 将在 ngClick 调用>删除锚。但我正在寻找更通用的解决方案。特别是因为我有很多页面有 许多 ngRepeats。
我正在考虑编写一个指令,该指令将放置在 Remove anchor 上,并会执行以下操作:
- 在父元素中查找 ngRepeat。
- 阅读它正在迭代的内容(第一种情况是'user.emails',第二种情况是'user.phones')
- 从 THAT 模型中移除 $index 元素。
所以标记看起来像这样:
<div ng-controller="MyController">
<div ng-repeat="email in user.emails">
{{ email }} <a href remove-directive="$index">Remove</a>
</div>
<div ng-repeat="phone in user.phones">
{{ phone }} <a href remove-directive="$index">Remove</a>
</div>
</div>
我正在寻找的目标是否可能实现?最好的方法是什么?
当前的 hacky 解决方案
这是我目前的做法。它既丑陋又丑陋,但在我找到更漂亮的方法之前可以完成工作。
myAppModule.controller('MyController', function ($scope, $parse, $routeParams, User) {
$scope.user = User.get({id: $routeParams.id});
$scope.remove = function ($index, $event) {
// TODO: Find a way to make a directive that does this. This is ugly. And probably very wrong.
var repeatExpr = $($event.currentTarget).closest('[ng-repeat]').attr('ng-repeat');
var modelPath = $parse(repeatExpr.split('in')[1].replace(/^\s+|\s+$/g, ''));
$scope.$eval(modelPath).splice($index, 1);
};
});
在 DOM 中:
<div ng-repeat="email in user.email" class="control-group">
<label class="control-label">
{{ "Email Address"|_trans }}
</label>
<div class="controls">
<input type="text" ng-model="email.address">
<span class="help-inline"><a href ng-click="remove($index, $event)">{{ "Delete"|_trans }}</a></span>
</div>
</div>
【问题讨论】:
-
“无 JS”是最好的答案。 (如果你只看一个投票最多的人)
标签: javascript angularjs angularjs-directive angularjs-scope