Ustaw zmienną zakresu kątowego w znacznikach


95

Proste pytanie: Jak mogę ustawić wartość zakresu w html, aby mój kontroler mógł go odczytać?

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/


Lepiej byłoby stworzyć dyrektywę, która to załatwi. Dyrektywa zawierałaby: parametr (y), kontroler specyficzny dla tej dyrektywy i szablon dla znaczników „myMap”.
Ian Mercer

Tak właśnie zrobiłem ... po prostu mam problemy z dostępem do $ scope.myVar w kontrolerze dyrektywy. Dlaczego muszę używać zegarka w kontrolerze, aby uzyskać dostęp do zmiennych zakresu?
Nix

1
Może mógłbyś zamieścić swoją dyrektywę? Spójrz na „Zrozumienie transkluzji i zakresów” tutaj docs.angularjs.org/guide/directive Prawdopodobnie potrzebujesz zakresu: {myVar: '='} i powiesz, my-var="foo"kiedy go wywołasz. Zwróć uwagę na użycie łącznika w porównaniu z camelCase. Uwaga: footutaj jest oceniane , jeśli nie chcesz, aby użycie znaku „@” w definicji zakresu miało dostęp do wartości atrybutu.
Ian Mercer

1
@Nix Czy możesz wyjaśnić, dlaczego wartość musi zostać zainicjowana w widoku, a nie w kontrolerze? Zakładam, że już wiesz, że to nie jest konwencjonalny sposób inicjowania wartości (w przeciwnym razie nie pytałbyś), a inni będą w stanie udzielić ci lepszych odpowiedzi, jeśli lepiej zrozumieją twój przypadek użycia.
Sean the Bean

1
@SeantheBean Byłem młody i głupi ...;) nie mam pojęcia, dlaczego musiałem to zrobić. Prawdopodobnie próbowałem coś zrobić.
Nix

Odpowiedzi:


139

ng-initnie działa, gdy przypisujesz zmienne wewnątrz pętli. Posługiwać się {{myVariable=whatever;""}}

Końcowe "" zatrzymuje obliczanie wyrażenia kątowego na dowolny tekst.

Wtedy możesz po prostu zadzwonić {{myVariable}} aby wyświetlić wartość zmiennej.

Okazało się, że jest to bardzo przydatne podczas iteracji wielu zagnieżdżonych tablic i chciałem zachować moje bieżące informacje o iteracji w jednej zmiennej zamiast wielokrotnego wykonywania zapytań.


1
Chociaż to działa, wydaje się być hackem. Oznacza to, że ogólnie dobrą praktyką jest używanie {{}}tylko do wyświetlania pojedynczej zmiennej, a nie do przypisywania zmiennych. Powiedziałbym, że stackoverflow.com/a/16799763/814160 jest bardziej poprawny (mniej kodu JS w widoku).
Sean the Bean

1
+1 dla @SeantheBean - przetestowałem to. Wydaje się, że występują problemy z kontrolerami podrzędnymi i zakresem przypisywania zmiennej w znaczniku. Dyrektywa działa dla moich celów i wydaje się być solidnym rozwiązaniem.
Paul Carlton,

2
Wydaje się, że to nie działa w angular2 / 4 - Wiązania nie mogą zawierać przypisań
Demodave

1
@Demodave powinieneś zamiast tego ustawić wszystkie zmienne kontrolera w kodzie Typescript i używać szablonu tylko do połączenia Typescript z HTML. Szablon nie powinien przypisywać zmiennych.
boxmein

81

ngInit może pomóc w inicjalizacji zmiennych.

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

przykład jsfiddle


3
Należy zauważyć, że nie polecają tego rozwiązania dla prawdziwych aplikacji (ale tak naprawdę nie sugerują alternatywy): docs.angularjs.org/guide/dev_guide.mvc.understanding_model
Mike Robinson

U mnie to zadziałało, jednak początkowo zmienna była nadal niezdefiniowana w kontrolerze. Zrobiłem małą pętlę interwałową: var interwał = setInterval (function () {if ($ scope.cokolwiek) {// dostuff clearInterval (interwał);}}, 10);
roelleor

19

Utwórz dyrektywę o nazwie myVarwith

scope : { myVar: '@' }

i nazwij to tak:

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

W szczególności należy zwrócić uwagę na odniesienie w dyrektywie do przypadku wielbłąda do nazwy znacznika z łącznikiem.

Aby uzyskać więcej informacji, zobacz „Understanding Transclusion and Scopes” tutaj: - http://docs.angularjs.org/guide/directive

Oto Fiddle, który pokazuje, jak można kopiować wartości z atrybutów do zmiennych zakresu na różne sposoby w ramach dyrektywy.


Chcę móc robić wiele var-nick='my' var-nick2='test'. Chyba że możesz wymyślić sposób na zaimplementowanie go za pomocą dyrektyw, których właśnie zamierzam użyćng-init
Nix

Możesz uwzględnić wiele atrybutów w zakresie, wystarczy, że jeden z nich będzie nazwą dyrektywy, którą chcesz wykonać (lub umieść tę nazwę również w kodzie HTML). scope: {varNick: '@', varNick2: '@'}
Ian Mercer

Ale nie jest skalowalne? Musiałbym zdefiniować dyrektywę dla każdej zmiennej?
Nix

Nie, nie potrzebujesz dyrektywy dla każdej zmiennej. Spójrz na skrzypce, które dodałem do odpowiedzi.
Ian Mercer,

Przepraszam, że tęsknię za przeczytaniem, Twój przykład jest doskonały, moją jedyną zmianą był zakres {'@': '@ "}.
Nix

10

Możesz ustawić wartości z html w ten sposób. Myślę, że nie ma jeszcze bezpośredniego rozwiązania z kątowego.

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

7
Niezły hack ... poleciłbym <div style="display: none">jednak.
Roger

3

Możesz użyć, ng-initjak pokazano poniżej

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

a następnie użyj zmiennej zakresu lokalnego w innych sekcjach:

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

Podoba mi się to podejście; wydaje się mniej hacky. Jedno wyjaśnienie, ng-init nie potrzebuje nawiasów klamrowych.
mklbtz

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


    }, true);

Zmienna inicjalizuje się po kontrolerze, więc musisz ją pilnować, a gdy nie jest zainicjalizowana, użyj jej.


0

Podoba mi się odpowiedź, ale myślę, że byłoby lepiej, gdybyś utworzył funkcję zasięgu globalnego, która pozwoli ci ustawić potrzebną zmienną zakresu.

Więc w globalController create

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

a następnie w swoim pliku html wywołaj to

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

Umożliwi to użycie zmiennej $ scope.myVar w odpowiednim kontrolerze


0

Jeśli nie jesteś w pętli, możesz użyć ng-init innego, którego możesz użyć

{{var=foo;""}}

"" pozwala nie wyświetlać twojego var

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.