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.