Imposta la variabile di ambito angolare nel markup


94

Domanda semplice: come posso impostare un valore di ambito in html, che deve essere letto dal mio controller?

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/


Potrebbe essere meglio creare una direttiva per gestire questo. Una direttiva incapsulerebbe: i parametri, un controller specifico per questa direttiva e un modello per il markup "myMap".
Ian Mercer

Questo è in realtà quello che ho fatto ... ho solo alcuni problemi con l'accesso a $ scope.myVar nel controller di direttiva. Perché devo utilizzare un orologio nel controller per accedere alle variabili di ambito?
Nix

1
Forse potresti pubblicare la tua direttiva? Dai un'occhiata a "Capire la transclusione e gli ambiti" qui docs.angularjs.org/guide/directive Probabilmente hai bisogno di scope: {myVar: '='} e diresti my-var="foo"quando lo chiami. Nota l'uso di trattino contro camelCase. Nota: fooqui viene valutato , se non si desidera utilizzare "@" nella definizione dell'ambito per accedere al valore dell'attributo.
Ian Mercer

1
@Nix Puoi spiegare perché il valore deve essere inizializzato nella vista, piuttosto che nel tuo controller? Presumo che tu sappia già che non è il modo convenzionale di inizializzare i valori (altrimenti non lo chiederesti), e altri saranno in grado di darti risposte migliori se capiscono meglio il tuo caso d'uso.
Sean the Bean

1
@SeantheBean ero giovane e sciocco ...;) non ho idea del perché avessi bisogno di farlo. Probabilmente stavo cercando di aggirare qualcosa.
Nix

Risposte:


138

ng-initnon funziona quando si assegnano variabili all'interno di loop. Uso {{myVariable=whatever;""}}

Il trailing ""interrompe la valutazione dell'espressione angolare su qualsiasi testo.

Quindi puoi semplicemente chiamare {{myVariable}}per visualizzare il valore della tua variabile.

L'ho trovato molto utile durante l'iterazione di più array annidati e volevo mantenere le mie attuali informazioni sull'iterazione in una variabile invece di interrogarle più volte.


1
Anche se funziona, sembra hacky. Cioè, è generalmente buona pratica usare {{}}solo per l'output di una singola variabile, non per l'assegnazione di variabili. Direi che stackoverflow.com/a/16799763/814160 è più corretto (meno codice JS nella vista).
Sean the Bean

1
+1 per @SeantheBean - L'ho provato. Sembra che ci siano problemi con i controller figlio e l'ambito di assegnazione della variabile nel markup. La direttiva funziona per i miei scopi e sembra essere una soluzione solida.
Paul Carlton

2
Questo non sembra funzionare in angular2 / 4 - I binding non possono contenere incarichi
Demodave

1
@Demodave dovresti invece impostare tutte le variabili del tuo controller nel codice Typescript e usare il template solo per connettere Typescript a HTML. Il modello non dovrebbe assegnare variabili.
boxmein

80

ngInit può aiutare a inizializzare le variabili.

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

jsfiddle esempio


3
Va notato che non consigliano questa soluzione per app reali (ma non suggeriscono davvero un'alternativa): docs.angularjs.org/guide/dev_guide.mvc.understanding_model
Mike Robinson

Questo ha funzionato per me, tuttavia, all'inizio la variabile era ancora indefinita nel controller. Ho fatto un piccolo ciclo di intervallo: var interval = setInterval (function () {if ($ scope.wwhat) {// dostuff clearInterval (interval);}}, 10);
roelleor

19

Crea una direttiva chiamata myVarcon

scope : { myVar: '@' }

e chiamalo così:

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

Notare in particolare il riferimento del caso del cammello nella direttiva al nome del tag con trattino.

Per ulteriori informazioni, vedere "Capire la transclusione e gli ambiti" qui: - http://docs.angularjs.org/guide/directive

Ecco un violino che mostra come copiare i valori dagli attributi alle variabili di ambito in vari modi diversi all'interno di una direttiva.


Voglio essere in grado di farne più di uno var-nick='my' var-nick2='test'. A meno che tu non riesca a pensare a un modo per implementarlo con le direttive che userò solong-init
Nix,

Puoi includere più attributi nello scope, tutto ciò di cui hai bisogno è che uno di essi sia il nome della direttiva che vuoi eseguire (o includi anche quel nome di direttiva nell'html). scope: {varNick: '@', varNick2: '@'}
Ian Mercer

Ma non è scalabile? Dovrei definire una direttiva per variabile?
Nix

No, non hai bisogno di una direttiva per variabile. Dai un'occhiata al violino che ho aggiunto alla risposta.
Ian Mercer

Scusa se mi manca la lettura, il tuo esempio è perfetto, la mia unica modifica è stata l'ambito {'@': '@ "}.
Nix,

10

Puoi impostare valori da html in questo modo. Non credo che ci sia ancora una soluzione diretta da angular.

 <div style="visibility: hidden;">{{activeTitle='home'}}</div>

7
Bel trucco ... lo consiglierei <div style="display: none">comunque.
Roger

3

È possibile utilizzare ng-initcome mostrato di seguito

<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>

e quindi utilizzare la variabile di ambito locale in altre sezioni:

<div>Total: BW: {{BWCount}}</div>
<div>Total: COLOR: {{ColorCount}}</div>

Mi piace questo approccio; sembra meno hacky. Un chiarimento, però, ng-init non ha bisogno delle parentesi graffe.
mklbtz

1
$scope.$watch('myVar', function (newValue, oldValue) {
        if (typeof (newValue) !== 'undefined') {
            $scope.someothervar= newValue;
//or get some data
            getData();
        }


    }, true);

La variabile si inizializza dopo il controller quindi è necessario controllarla e quando non è inizializzata la si usa.


0

Mi piace la risposta, ma penso che sarebbe meglio creare una funzione di ambito globale che ti consentirà di impostare la variabile di ambito necessaria.

Quindi nel globalController creare

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

e poi nel tuo file html chiamalo

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

Questo ti permetterà quindi di usare $ scope.myVar nel tuo rispettivo controller


0

Se non sei in un ciclo, puoi usare ng-init altrimenti puoi usare

{{var=foo;""}}

il "" consente di non visualizzare la tua variabile

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.