2014-05-18 6 views
35

Es gibt offensichtlich etwas Grundlegendes, das ich noch nicht verstehe.Warum funktioniert ng-click nicht in case-1, aber in case-3?

Ich versuche, Benutzer des Modal-Moduls in Angular Ui.Bootstrap zu machen, aber ich finde, dass meine Klicks nicht die open() Funktion aktivieren - So kochend es auf einen sehr einfachen Testfall, wie unten, sehe ich keine Anrufe wenn der ng-click auf eine Funktion verweist (alert oder console.log), aber funktioniert, wenn der ng-click auf etwas zeigt, das nur ein Ausdruck ist

Warum wird alert im ersten Beispiel nicht aufgerufen?

<div data-ng-app> 
    <button data-ng-click="alert('Message 1');"> 
     ngClick -- not working, why not? 
    </button> 
    <button onclick="alert('Message 2');"> 
     Plain onclick 
    </button> 
    <button data-ng-click="count = (count + 1)"> 
      But this works, why ??? 
    </button> 
    count: {{count}} 
</div> 

http://jsfiddle.net/H2wft/1/

Antwort

47

ng-click wird entweder mit in dem aktuellen Bereich eine Funktion zur Verwendung gedacht (so beispielsweise $scope.alert = window.alert würde löst das Problem nicht, dass es alarmieren zu können), oder einen Winkelausdruck. Es sieht so aus, als ob eckige es nicht erlaubt, globale Scope-Methoden dort zu verwenden (es könnte sie im aktuellen $scope suchen, von dem sie fehlen).

4

Dafür arbeiten Sie alert auf $scope zu definieren:

$scope.alert = function(text) { 
    alert(text); 
}; 

Relevante Stück von Dokumentation:

AngularJS schränkt den Zugriff auf das Fensterobjekt aus Ausdrücke, da es ein ist bekannter Weg, um Javascript Code auszuführen.

https://docs.angularjs.org/error/ $ Parse/isecwindow

7

Sie können nicht diese Art von Code in ng Richtlinien auszuführen. Sie suchen nach Inhalten in Ihrem lokalen Bereich.

Wenn Sie tun dies in Ihrem Controller:

$scope.alert = function(){ 
    alert('alerted!'); 
}; 

und dann in der Vorlage

ng-click="alert()" 

Es wird die Javascript-Alarm richtig auszuführen.

21

ng-click erwartet eine angular expression. Intern verwendet angular den Dienst $parse, um die expression in ng-click="expression" auszuwerten.

Ein eckiger Ausdruck ist nicht dasselbe wie normaler JavaScript-Code. $parse verwendet String-Parsing zum Interpretieren des Ausdrucks und beschränkt den Zugriff auf Variablen, Funktionen und Objekte auf Objekte, die Eigenschaften des Objekts $scope sind, oder auf Eigenschaften von $parent Scope-Objekten, die weiter oben in prototypical inheritance chain verfügbar sind.

Also in der Theorie könnten Sie den Zugriff auf Globals wie folgt gewinnen:

$scope.window = window; 
$scope.alert = alert; 

...und dann in der Vorlage tun ng-click="window.alert('hello!')"

... oder ... ng-click="alert('hello!')"


Oder Sie könnten dies tun, nur ein einziges Mal: ​​

$rootScope.window = window; 
$rootScope.alert = alert; 

Dann jeder Bereich, der prototypisch von $rootScope erbt wird haben auch Zugriff auf Fenster und Alarm.


... aber es gibt gute Gründe, keines der oben genannten zu tun, außer möglicherweise zu Debugging-Zwecken. Das ist nicht zu sagen, dass das Dekorieren der $rootScope immer eine schlechte Idee ist, gibt es mindestens one special case where decorating angular's scope can accomplish something that would be very difficult to do otherwise.

0

https://docs.angularjs.org/guide/expression

<div class="example2" ng-controller="ExampleController"> 
    Name: <input ng-model="name" type="text"/> 
    <button ng-click="greet()">Greet</button> 
    <button ng-click="window.alert('Should not see me')">Won't greet</button> 
</div> 
+2

Könnten Sie erklären, wie dies die Frage beantwortet? – Soren

Verwandte Themen