2016-06-17 6 views
4

AngularJS Direktiven 'link Funktion ändern isolieren Scope-Daten nicht in UI wider. Hier

ein Beispiel:

var myApp = angular.module('myApp', []); 

myApp.directive('myDirective', function() { 
    return { 
     restrict: 'A', 
     template: '<span>Title: {{myParams.title}}</span>', 
     scope: { 
      myParams: '=' 
     }, 
     link: function ($scope) { 
      // the new value is not reflected in ui 
      $scope.myParams.title = 'this is myDirective'; 
     } 
    }; 
}); 

HTML:

<div my-directive my-params="{title: 'this is title'}"></div> 

ich die HTML-Seite will this is myDirective angezeigt werden, aber in der Tat ist es this is title.

Darüber hinaus könnten Sie erklären, warum es so angezeigt wird. Danke

+0

was ist das 'my-params'? –

Antwort

5

Der Grund ist, dass die my-params="{title: 'this is title'}" eine Konstante Ausdruck und nicht zuweisbar ist. Auch wenn Sie versuchen, die Eigenschaft 'title' zu überschreiben, wird sie von der Konstante überschrieben. Überprüfen Sie this fiddle. Es enthält Ihren Code und ist auf Angular 1.4 eingestellt. Mit dem Unterschied, dass die Richtlinie einmal verwendet wird, wie oben und einmal mit einer wechselbaren, nichtkonstanten Wert von einem Controller:

<div ng-app="app" ng-controller="Ctrl as ctrl"> 
    <div my-directive my-params="{title: 'this is title'}"></div> 
    <div my-directive my-params="data"></div> 
</div> 

Der zweite Instanz (nicht konstante Ausdruck) arbeitet.

Versuchen Sie jetzt, die Angular-Version auf 1.2 zu ändern. Beachten Sie, dass jetzt Angular einen unendlichen verdauen Fehler wirft:

VM1033 angular.js:9101 Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! 
Watchers fired in the last 5 iterations: [["fn: parentValueWatch; newVal: {\"title\":\"this is title\"}; oldVal: {\"title\":\"this is title\"}"],["fn: parentValueWatch; newVal: {\"title\":\"this is title\"}; oldVal: {\"title\":\"this is title\"}"],["fn: parentValueWatch; newVal: {\"title\":\"this is title\"}; oldVal: {\"title\":\"this is title\"}"],["fn: parentValueWatch; newVal: {\"title\":\"this is title\"}; oldVal: {\"title\":\"this is title\"}"],["fn: parentValueWatch; newVal: {\"title\":\"this is title\"}; oldVal: {\"title\":\"this is title\"}"]] 

Der Ausdruck in der Richtlinie angegeben ist (dh my-params="{title: 'this is title'}") versucht, das Richtlinie scope-Attribut zu überschreiben (immer ein neues Objekt in 1.2, also die unendliche Digest zu schaffen) .

0

Die link Funktion wird nur einmal ausgeführt, wenn die directive initialisiert wird. So der Wert auf myParams.title aus dem Inneren der link Funktion in dieser Phase zugeordnet ist (aber es würde später bekommen außer Kraft gesetzt) ​​

Danach können Sie den Wert von my-params in dem Attribut aktualisiert haben (die separat beobachtet werden würde und aktualisiert durch die Winkel). Der Wert im Attribut ist der letzte Wert für myParam.title und wird in der Benutzeroberfläche angezeigt.

Im Fall möchten Sie einen neuen Wert setzen, können Sie eine Klick-Funktion (oder einem anderen Event-Handler) haben innerhalb link, was den Wert wie folgt ändern:

in Controller:

$scope.myparams = {title: 'this is title'}; 

in UI:

<div my-directive my-params="myparams"></div> 

in Richtlinie:

.directive('myDirective', function() { 
    return { 
     restrict: 'A', 
     template: '<span> Title: {{myParams.title}} </span>', 
     scope: { 
      myParams: '=' 
     }, 
     link: function ($scope,element) { 
      // the new value is not reflected in ui 

      element.click(function(){ 
       $scope.myParams.title = 'this is myDirective'; 
       $scope.$apply(); 
      }) 
     } 
    }; 
}); 
+0

Da der aktualisierte Wert dem im Attribut angegebenen Wert entspricht, wurde die Verknüpfungsfunktion bereits ausgeführt, bevor der Attributwert zugewiesen wird. Daher ist der Attributwert der letzte Wert. – gaurav5430

Verwandte Themen