2015-01-14 6 views
9

Sagen wir, ich habe den folgenden CodeKann eine Richtlinie löschen sich aus einem übergeordneten Bereich

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

Und meine benutzerdefinierte Richtlinie hat einen isolierten Umfang, definiert als:

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

In dieser Richtlinie I muss Option haben, um es zu löschen. Meine Frage ist, wie kann ich zurück zu den Array-Instanzen im übergeordneten Bereich kommunizieren und ihm sagen, dieses Objekt zu zerstören und in der Tat die gelöschte Instanz aus meinem DOM zu entfernen?

Hoffnung, die Sinn macht.

+0

scheint, wie man es rückwärts suchen ... entfernen Sie die Instanz-Objekt aus Modellanordnung, Winkel nimmt Pflege des DOM für Sie – charlietfl

+0

@Matt, könnten Sie in Betracht ziehen, Ihr Häkchen auf die andere Antwort zu verschieben. Es scheint, dass der allgemeine Konsens ist, dass dieser Ansatz bevorzugt wird. –

Antwort

30

nach New Dev in einem previous comment, das ist die Art und Weise:

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

fehlerfrei. Glatt wie keine andere Antwort, die ich gesehen habe! Vielen Dank! – Dazag

+0

Hervorragende Lösung –

3

Erstens, verwenden Sie nicht ngModel als ein DOM-Attribut. Dies ist eine AngularJS-Direktive, die verwendet wird, um Formulareingaben an Bereichsvariablen zu binden.

Ich habe es in model umbenannt und ein zusätzliches Attribut namens index hinzugefügt.

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

Jetzt in Ihrem Controller können Sie für Ereignisse (wie ein benutzerdefiniertes Ereignis, das Sie vielleicht Titel removeCustom) hören von Kindern emittieren $scope.$on() verwenden.

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

Dann in Ihrer benutzerdefinierten Richtlinie Sie haben $scope.$emit() benutzen, um Ihre removeCustom Ereignis bis den Umfang Hierarchie an die Steuerung zu übertragen.

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); 
     } 
    }); 

FYI: Eine Richtlinie kann jederzeit wieder entfernen selbst durch $el.remove() in der Link-Funktion aufrufen, aber da Ihre Richtlinie über eine ngRepeat erstellt wird, wird es nur in der nächsten Digest neu erhalten. Sie müssen also dem Controller mitteilen, dass er es aus dem Array instances entfernen soll.

+5

'$ emit' scheint hier unpassend zu sein, da es den globalen Geltungsbereich" verschmutzt ". Ich würde '" & "' - einen Funktionsaufruf von der Direktive verwenden. –

+0

@NewDev ja, ich stimme zu. Das wäre ein besserer Ansatz. – cgTag

+6

Verwenden Sie 'delete' nicht für Arrays, das Element wird nicht entfernt. Verwenden Sie' splice() ', um die Länge zu ändern und kein undefiniertes Element im Array zu belassen. Im Allgemeinen ist es besser, das tatsächliche Objekt zu übergeben und sich nicht auf seinen Ansichtsindex zu verlassen, der aufgrund der Filterung anders sein könnte, dann benutze 'indexOf', um es zu entfernen. – charlietfl

Verwandte Themen