Legen Sie die Winkelbereichsvariable im Markup fest

94

Einfache Frage: Wie kann ich einen Bereichswert in HTML festlegen, der von meinem Controller gelesen werden soll?

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

app.controller('MyController', function($scope) {
  console.log($scope.myVar);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app'>
  <div ng-controller="MyController" app-myVar="test">
    {{myVar}}
  </div>
</div>

JSFiddle: http://jsfiddle.net/ncapito/YdQcX/

Nix
quelle
Möglicherweise ist es besser, eine Direktive zu erstellen, um dies zu handhaben. Eine Direktive würde Folgendes einschließen: die Parameter, einen für diese Direktive spezifischen Controller und eine Vorlage für das Markup 'myMap'.
Ian Mercer
Das ist eigentlich das, was ich getan habe ... nur einige Probleme mit dem Zugriff auf $ scope.myVar im Direktiven-Controller. Warum muss ich eine Uhr in der Steuerung verwenden, um auf die Bereichsvariablen zuzugreifen?
Nix
1
Vielleicht könnten Sie Ihre Richtlinie veröffentlichen? Werfen Sie hier einen Blick auf "Transklusion und Bereiche verstehen" docs.angularjs.org/guide/directive Sie benötigen wahrscheinlich den Bereich: {myVar: '='} und Sie würden sagen, my-var="foo"wenn Sie ihn aufrufen. Beachten Sie die Verwendung von Bindestrich vs. camelCase. Hinweis: fooHier wird ausgewertet , wenn Sie nicht möchten, dass '@' in der Bereichsdefinition verwendet wird, um auf den Wert des Attributs zuzugreifen.
Ian Mercer
1
@Nix Können Sie erklären, warum der Wert in der Ansicht und nicht in Ihrem Controller initialisiert werden muss? Ich gehe davon aus, dass Sie bereits wissen, dass dies nicht die herkömmliche Methode zum Initialisieren von Werten ist (sonst würden Sie nicht danach fragen), und andere können Ihnen bessere Antworten geben, wenn sie Ihren Anwendungsfall besser verstehen.
Sean the Bean
1
@SeantheBean Ich war jung und dumm ...;) Ich habe keine Ahnung, warum ich es tun musste. Ich habe wahrscheinlich versucht, etwas herumzuhacken.
Nix

Antworten:

138

ng-initfunktioniert nicht, wenn Sie Variablen innerhalb der Schleife zuweisen. Verwenden {{myVariable=whatever;""}}

Das Schleppen "" der Winkelausdruck für einen beliebigen Text ausgewertet wird.

Dann können Sie einfach anrufen {{myVariable}} um Ihren Variablenwert auszugeben.

Ich fand dies sehr nützlich, wenn ich mehrere verschachtelte Arrays iterierte, und ich wollte meine aktuellen Iterationsinformationen in einer Variablen behalten, anstatt sie mehrmals abzufragen.

Glogo
quelle
1
Obwohl dies funktioniert, scheint es hacky. Das heißt, es ist im Allgemeinen eine gute Praxis zu verwenden{{}} nur eine einzelne Variable auszugeben, nicht Variablen zuzuweisen. Ich würde sagen, stackoverflow.com/a/16799763/814160 ist korrekter (weniger JS-Code in der Ansicht).
Sean the Bean
1
+1 für @SeantheBean - Ich habe dies getestet. Es scheint Probleme mit untergeordneten Controllern und dem Umfang der Zuweisung der Variablen im Markup zu geben. Die Richtlinie funktioniert für meine Zwecke und scheint eine solide Lösung zu sein.
Paul Carlton
2
Dies scheint in angle2 / 4 nicht zu funktionieren - Bindungen können keine Zuweisungen enthalten
Demodave
1
@Demodave Sie sollten stattdessen alle Ihre Controller-Variablen in Typescript-Code festlegen und die Vorlage nur verwenden, um Typescript mit HTML zu verbinden. Die Vorlage sollte keine Variablen zuweisen.
Boxmein
80

ngInit kann helfen, Variablen zu initialisieren.

<div ng-app='app'>
    <div ng-controller="MyController" ng-init="myVar='test'">
        {{myVar}}
    </div>
</div>

jsfiddle Beispiel

Mark Coleman
quelle
3
Es sollte beachtet werden, dass sie diese Lösung nicht für echte Apps empfehlen (aber keine Alternative vorschlagen): docs.angularjs.org/guide/dev_guide.mvc.understanding_model
Mike Robinson
Dies funktionierte bei mir jedoch zunächst war die Variable im Controller noch undefiniert. Ich habe eine kleine Intervallschleife erstellt: var interval = setInterval (function () {if ($ scope.whatever) {// dostuff clearInterval (interval);}}, 10);
Roelleor
19

Erstellen Sie eine Direktive, die myVarmit aufgerufen wird

scope : { myVar: '@' }

und nenne es so:

<div name="my_map" my-var="Richmond,VA">

Beachten Sie insbesondere den Kamelfallverweis in der Direktive auf den mit Bindestrich versehenen Markennamen.

Weitere Informationen finden Sie unter "Grundlegendes zu Transklusion und Umfang" hier: - http://docs.angularjs.org/guide/directive

Hier ist eine Geige , die zeigt, wie Sie Werte aus Attributen auf verschiedene Arten innerhalb einer Direktive in Bereichsvariablen kopieren können.

Ian Mercer
quelle
Ich möchte in der Lage sein, mehrere zu machen var-nick='my' var-nick2='test'. Es sei denn, Sie können sich eine Möglichkeit ng-init
Nix
Sie können mehrere Attribute in den Bereich aufnehmen. Sie müssen lediglich den Namen der Direktive angeben, die Sie ausführen möchten (oder diesen Direktivennamen auch in den HTML-Code aufnehmen). scope: {varNick: '@', varNick2: '@'}
Ian Mercer
Aber es ist nicht skalierbar? Ich müsste eine Direktive pro Variable definieren?
Nix
Nein, Sie benötigen keine Direktive pro Variable. Schauen Sie sich die Geige an, die ich der Antwort hinzugefügt habe.
Ian Mercer
Entschuldigung, ich vermisse das Lesen, Ihr Beispiel ist perfekt. Meine einzige Änderung war der Bereich {'@': '@ "}.
Nix
10

Sie können Werte wie folgt in HTML festlegen. Ich denke, es gibt noch keine direkte Lösung von Angular.

 <div style="visibility: hidden;">{{activeTitle='home'}}</div>
ibsenv
quelle
7
Netter Hack ... würde aber empfehlen <div style="display: none">.
Roger
3

Sie können ng-initwie unten gezeigt verwenden

<div class="TotalForm">
  <label>B/W Print Total</label>
  <div ng-init="{{BWCount=(oMachineAccounts|sumByKey:'BWCOUNT')}}">{{BWCount}}</div>
</div>
<div class="TotalForm">
  <label>Color Print Total</label>
  <div ng-init="{{ColorCount=(oMachineAccounts|sumByKey:'COLORCOUNT')}}">{{ColorCount}}</div>
</div>

und verwenden Sie dann die lokale Bereichsvariable in anderen Abschnitten:

<div>Total: BW: {{BWCount}}</div>
<div>Total: COLOR: {{ColorCount}}</div>
Mahesh
quelle
Ich mag diesen Ansatz; scheint weniger hacky. Eine Klarstellung: ng-init benötigt keine geschweiften Klammern.
mklbtz
1
$scope.$watch('myVar', function (newValue, oldValue) {
        if (typeof (newValue) !== 'undefined') {
            $scope.someothervar= newValue;
//or get some data
            getData();
        }


    }, true);

Die Variable wird nach dem Controller initialisiert, sodass Sie darauf achten müssen und wenn sie nicht initialisiert ist, verwenden Sie sie.

Senad Mulaosmanović
quelle
0

Ich mag die Antwort, aber ich denke, es wäre besser, wenn Sie eine globale Bereichsfunktion erstellen, mit der Sie die erforderliche Bereichsvariable festlegen können.

Also im globalController erstellen

$scope.setScopeVariable = function(variable, value){
    $scope[variable] = value;
}

und dann in Ihrer HTML-Datei rufen Sie es auf

{{setScopeVariable('myVar', 'whatever')}}

Auf diese Weise können Sie $ scope.myVar in Ihrem jeweiligen Controller verwenden

Lance N. Solomon
quelle
0

Wenn Sie sich nicht in einer Schleife befinden, können Sie ng-init verwenden, andernfalls können Sie verwenden

{{var=foo;""}}

Die "" Alows zeigen Ihre Var nicht an

Yohann JAFFRES
quelle