2014-01-28 6 views
6

Ich versuche, eine Direktive mit einer Link-Funktion zu erstellen, wo sie den "varName" im Bereich (d. H. Im Eingabe-Tag) ändern kann. Beachten Sie, dass die Direktivenvorlage denselben "varName" wie in der Steuerung & hat, keine scope-Eigenschaft verwendet wird.AngularJs Direktive Link-Funktion kann die im Controller-Bereich definierte Variable nicht ändern

Hier ist, was passiert ist:

Fall 1: Wenn ich das benutzerdefinierte Element klicken, wird die „runFn“ -Funktion in der $ Bereich definiert aufgerufen wird, aber die „varName“ wird nicht geändert.

Fall 2: Wenn ich auf das div-Tag klicke, wird auch die "runFn" -Funktion aufgerufen UND der "varName" wird geändert.

Ich habe 3 Ansätze versucht, aber kann nicht scheinen, die Link-Funktion zu bekommen, um den "varName" -Wert zu ändern. Kann jemand erklären, warum n bitte eine Lösung anbieten? Vielen Dank.

Code:

<body ng-app="moduleA"> 
<div ng-controller="ctrlA"> 
    <input type="text" ng-model="varName"> 
    <custom></custom> 
    <div ng-click="runFn()">click for new value</div> 
</div> 
<script> 
window.onload=(function(){ 
    "use strict"; 
    var app = angular.module('moduleA', []); 
    app.controller("ctrlA", function($scope){ 
     $scope.varName = "old value"; 
     $scope.runFn = function(){ 
      $scope.varName = "new value"; 
      console.log("run fn"); 
     }; 
    }); 
    app.directive("custom", function(){ 
     return { 
      restrict: "E",   
      template: '<div>{{varName}}</div>', 
      replace: true, 
      link: function(s, e, a){ 
       e.on("click", function(){ 
        s.varName = "new value"; //didn't work 
        s.runFn();  //didn't work 
        s.runFn.call(s); //didn't work 
       }); 
      } 
     }; 

    });  
})(); // end windows onload 
</script> 
</body> 

Antwort

13

Ich glaube, alles, was Sie vergessen werden, ist $ anwenden zu rufen, wenn Sie die Updates, um sicherzustellen, dass die Benutzeroberfläche aktualisiert wird.

e.on("click", function(){ 
    //Call $apply to ensure a $digest loop 
    // get's kicked off 
    s.$apply(function(){ 
    s.varName = "new value"; 
    }); 
}); 
+0

Dank. Ich dachte, der Link fn wird automatisch aktualisiert. – Charles

+0

nur fragen, ob es eine Möglichkeit gibt, die Gesamtsyntax zu vereinfachen, aus der Link-Funktion Perspektive? Ich meine, es gibt 3 Funktionen innerhalb der Direktive verschachtelt, 2 innerhalb der Link-Funktion verschachtelt. – Charles

+0

@Charles - Ich weiß, es sieht ein wenig Cluddy, aber Anweisungen sind sowieso Low-Level-Jungs. Sie sollen alle unangenehmen DOM-Manipulationen vor dem Anwendungscode verbergen. Es hängt wirklich davon ab, was Sie in Ihrer Richtlinie tun, die entscheiden wird, wie komplex es ist. Wenn es zu komplex ist, können Sie immer einen Direktiven-Controller verwenden. – Josh

1

Ihre Klick-Funktion wird aus Winkel ausgeführt. Sie müssen das Klickereignis in eckiger Form behandeln. Ändern Sie Ihre Richtlinie wie folgt

app.directive("custom", function(){ 
    return { 
     restrict: "E",   
     template: '<div ng-click="divClick()">{{varName}}</div>', 
     replace: true, 

     link: function(s, e, a){ 

      s.divClick = function(){   
       s.varName = "new value"; 
       s.runFn();  
       s.runFn.call(s); 
      } 
     } 
    }; 
}); 

JSBIN