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

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/

Nix
источник
Возможно, вам будет лучше создать директиву для решения этой проблемы. Директива инкапсулирует: параметр (ы), контроллер, специфичный для этой директивы, и шаблон для разметки 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>
ibsenv
источник
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

Йоханн ДЖАФРЕС
источник