指令可以从父作用域中删除自身

时间:2015-01-14 01:26:24

标签: javascript angularjs angularjs-scope angular-directive

我们说我有以下代码

<div ng-app="app" ng-controller="controller">
 <div ng-repeat="instance in instances>
  <customDirective ng-model="instance"></customDirective>
 </div>
</div>

我的自定义指令有一个独立的范围,定义为:

 app.directive('customDirective', function($log) {
        return {
            restrict: 'E',
            templateUrl: './template.htm',
            scope: {_instance:"=ngModel"},
            link: function($scope) {
            ....
            }
        });

在这个指令中,我必须选择删除它。我的问题是如何与父作用域中的数组实例进行通信并告诉它销毁此对象并实际上从我的DOM中删除已删除的实例?

希望这是有道理的。

2 个答案:

答案 0 :(得分:31)

根据previous comment中的新开发,这就是:

var app = angular.module('app', [])
  .directive('customDirective', function($log) {
    return {
        restrict: 'EA',
        template: '<a href="" ng-click="onRemove()">remove me {{model.n}}</a>',
        scope: {
            model:"=",
            onRemove:"&"
        }
    }
  })
  .run(function($rootScope) {
    $rootScope.instances = [{n:1},{n:2},{n:3},{n:4}];
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <div ng-repeat="i in instances">
    <custom-directive model="i" on-remove="instances.splice($index,1)">
    </custom-directive>
  </div>
</div>

答案 1 :(得分:3)

首先,不要将ngModel用作DOM属性。这是一个AngularJS指令,用于将表单输入绑定到范围变量。

我已将其重命名为model并添加了一个名为index的额外属性。

<div ng-app="app" ng-controller="controller">
  <div ng-repeat="instance in instances>
    <customDirective model="instance" index="$index"></customDirective>
  </div>
</div>

现在,在您的控制器中,您可以使用removeCustom收听儿童发出的事件(例如您可能标题为$scope.$on()的自定义事件)。

app.controller('controller',function($scope) {
    $scope.instances = [.....];
    $scope.$on('removeCustom',function($index) {
        delete $scope.instances[$index];
    });
});

然后,在您的自定义指令中,您必须使用$scope.$emit()将您的removeCustom事件向上范围层次结构广播到控制器。

app.directive('customDirective', function($log) {
    return {
        restrict: 'E',
        templateUrl: './template.htm',
        scope: {
            model:"=",
            index:"="
        },
        link: function($scope,$el,$attr) {
            // when you need to remove this
            $scope.$emit('removeCustom',$scope.index);
        }
    });

仅供参考:指令总是可以通过在链接函数中调用$el.remove()来删除本身,但由于您的指令是通过ngRepeat创建的,因此它将在下一个摘要。因此,您必须告诉控制器将其从instances数组中删除。