Установить переменную угловой области в разметке


95

Простой вопрос: как установить значение области видимости в html, чтобы его мог читать мой контроллер?

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/


Возможно, вам будет лучше создать директиву для решения этой проблемы. Директива инкапсулирует: параметр (ы), контроллер, специфичный для этой директивы, и шаблон для разметки myMap.
Ян Мерсер

На самом деле это то, что я сделал ... просто возникли проблемы с доступом к $ scope.myVar в контроллере директив. Почему мне нужно использовать часы в контроллере для доступа к переменным области видимости?
Nix

1
Может, вы могли бы опубликовать свою директиву? Взгляните на "Общие сведения о включении и областях" здесь docs.angularjs.org/guide/directive Вам, вероятно, понадобится область действия: {myVar: '='}, и вы бы сказали, my-var="foo"когда ее вызываете. Обратите внимание на использование дефиса и верблюжьего регистра. Примечание: fooздесь оценивается , если вы не хотите, чтобы использование '@' в определении области видимости обращалось к значению атрибута.
Ян Мерсер

1
@Nix Можете ли вы объяснить, почему значение нужно инициализировать в представлении, а не в вашем контроллере? Я предполагаю, что вы уже знаете, что это необычный способ инициализации значений (иначе вы бы не спросили), и другие смогут дать вам лучшие ответы, если они лучше поймут ваш вариант использования.
Шон Бин,

1
@SeantheBean, я был молод и глуп ...;) я понятия не имею, зачем мне это нужно. Я, наверное, пытался что-то взломать.
Nix

Ответы:


139

ng-initне работает, когда вы назначаете переменные внутри цикла. Использовать {{myVariable=whatever;""}}

Завершение ""останавливает вычисление выражения Angular для любого текста.

Затем вы можете просто позвонить, {{myVariable}}чтобы вывести значение переменной.

Я нашел это очень полезным при итерации нескольких вложенных массивов, и я хотел сохранить мою текущую информацию об итерации в одной переменной, а не запрашивать ее несколько раз.


1
Хотя это работает, это кажется хакерским. То есть, как правило, рекомендуется использовать {{}}только для вывода одной переменной, а не для назначения переменных. Я бы сказал, что stackoverflow.com/a/16799763/814160 более правильный (меньше кода JS в представлении).
Шон Бин,

1
+1 за @SeantheBean - я это тестировал. Похоже, есть проблемы с дочерними контроллерами и областью назначения переменной в разметке. Директива подходит для моих целей и кажется надежным решением.
Пол Карлтон,

2
Похоже, это не работает в angular2 / 4 - привязки не могут содержать присваивания
Demodave

1
@Demodave вы должны вместо этого установить все переменные вашего контроллера в коде Typescript и использовать шаблон только для подключения Typescript к HTML. Шаблон не должен назначать переменные.
boxmein 04

81

ngInit может помочь инициализировать переменные.

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

jsfiddle пример


3
Следует отметить, что они не рекомендуют это решение для реальных приложений (но на самом деле не предлагают альтернативы): docs.angularjs.org/guide/dev_guide.mvc.understanding_model
Майк Робинсон

Это сработало для меня, однако сначала переменная еще не была определена в контроллере. Я сделал небольшой интервальный цикл: var interval = setInterval (function () {if ($ scope.whatever) {// dostuff clearInterval (interval);}}, 10);
roelleor

19

Создайте директиву myVarс именем

scope : { myVar: '@' }

и назовите это так:

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

Обратите внимание, в частности, на ссылку в директиве на имя тега, написанное через дефис.

Для получения дополнительной информации см. «Общие сведения о включении и областях» здесь: - http://docs.angularjs.org/guide/directive

Вот сценарий, который показывает, как можно копировать значения из атрибутов в переменные области видимости различными способами в пределах директивы.


Я хочу иметь возможность делать несколько var-nick='my' var-nick2='test'. Если вы не можете придумать способ реализовать это с помощью директив, я просто собираюсь использоватьng-init
Nix

Вы можете включить несколько атрибутов в область видимости, все, что вам нужно, это чтобы один из них был именем директивы, которую вы хотите выполнить (или включите это имя директивы также в html). scope: {varNick: '@', varNick2: '@'}
Ian Mercer

Но его нельзя масштабировать? Мне нужно было бы определить директиву для каждой переменной?
Nix

Нет, вам не нужна директива для каждой переменной. Взгляните на скрипку, которую я добавил к ответу.
Ian Mercer

Извините, я пропустил чтение, ваш пример идеален, мое единственное изменение - это область действия {'@': '@ "}.
Nix,

10

Вы можете установить значения из html вот так. Не думаю, что у angular пока есть прямое решение.

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

7
Хороший хак ... <div style="display: none">однако рекомендую .
Роджер

3

Вы можете использовать, ng-initкак показано ниже

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

а затем используйте переменную локальной области видимости в других разделах:

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

Мне нравится такой подход; кажется менее хакерским. Одно уточнение: ng-init не нуждается в фигурных скобках.
mklbtz

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


    }, true);

Переменная инициализируется после контроллера, поэтому вам нужно следить за ней и использовать ее, когда она не инициализирована.


0

Мне нравится ответ, но я думаю, было бы лучше, если бы вы создали функцию глобальной области видимости, которая позволит вам установить необходимую переменную области.

Итак, в globalController создайте

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

а затем в вашем html файле назовите его

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

Это позволит вам использовать $ scope.myVar в соответствующем контроллере.


0

Если вы не в цикле, вы можете использовать ng-init, иначе вы можете использовать

{{var=foo;""}}

"" позволяет не отображать ваш var

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.