Angular: Где хранятся переменные, если они установлены в ng-init?

0

Где именно хранится эта переменная ng-init "someData"?

<tr data-ng-repeat="item in items" ng-init="someData=1">
 <td>{{item.id}}</td>
 <td>{{someData}}</td>
</tr>

Как я могу получить к нему доступ извне, т.е. Из функции, которая должна установить someData = someData + 1?

  • 0
    по scope как обычно
  • 0
    Под областью вы подразумеваете «предмет»? Я не могу найти это там. Извините, я все еще не могу понять, как работает JS из C #.
Показать ещё 1 комментарий
Теги:
angularjs-scope
angularjs-ng-repeat

1 ответ

0

Переменные, определенные в представлении, определяются в текущей области. Тем не менее, не всегда так легко узнать, какова ваша текущая область. Ваша текущая область действия определяется ближайшим элементом, который создает область действия.

Простой случай

Если вы находитесь непосредственно внутри контроллера, то ваша текущая область действия является переменной $ scope этого контроллера. Как и в следующем примере:

В вашем HTML
<div ng-controller="MyController">
    <div ng-init="someData = 1">
    </div>
</div>
в MyController
$timeout(function() {
    console.log($scope.someData); // Logs 1
})

Переменная "someData" была определена в области MyController. Обратите внимание на тайм-аут, это необходимо, потому что контроллер запускается до того, как будет проанализирован вид, поэтому, если мы запишемся немедленно, ng-init еще не будет запущен, а переменная не определена.

Если вы должны были вложить два контроллера, а затем сделать ng-init внутри, он будет назначать ближайший. Поэтому, если у вас есть контроллер A и внутри, у вас есть контроллер B и внутри, вы выполняете ng-init, тогда он назначит переменную внутри контроллера B, а не A.

Чем меньше случай симпель

Если вы попробуете вышеуказанное решение с вашим кодом, это не сработает. Причина в том, что вы используете ретранслятор. Ng-repeat, наряду с большинством других директив, создаст свои собственные области применения! В вашем случае некоторые данные будут определены во внутренней области репитера, недоступной вашему контроллеру! Это кстати, где переменная "item" из повтора сохраняется в локальной области репитера для этой строки. Каждая строка в ретрансляторе получает свою собственную область видимости, поэтому вы используете одну и ту же переменную "item" в каждой строке, но каждый раз она означает разные вещи.

<div ng-controller="MyController">
    We are now in the scope of MyController.
    Variables defined here can be find in $scope of MyController.

    <div ng-repeat="foo in bar">
        We are now in the local repeater scope, one for each row.
        Note that the containing div is part of the scope.
        Variables defined here go on the local scope, MyController can't find them.
    </div>

    The repeater scope has ended, we are back in MyController

    <div ng-include="someview.html">
       And now we are in the local scope of the ng-include!
       This scope works just like the ng-repeat one does.
    </div>
</div>

Это связано с тем, как наследование работает в javascript. Обратите внимание: если вы хотите получить переменную, которая существует только у родителя (скажем, распечатывать ее), она будет работать нормально. В javascript, когда вы получаете переменную, он увеличит цепочку наследования до тех пор, пока не найдет ее. Vut, как только вы попытаетесь присвоить значение чему-то, он создает собственную локальную переменную, а затем использует это вместо этого.

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

Лучший способ

Существует несколько способов обойти это. Рекомендуемым способом является использование контроллера в качестве синтаксиса. Он описан в документации для ng-контроллера, но вкратце вы назначаете свои переменные непосредственно объекту контроллера (а не на объекте $ scope), а затем присваиваете вашему контроллеру имя при вызове его в вашем представлении. Это позволяет вам четко указать, какую переменную, с которой вы следуете.

В MyController
this.data = {};
В вашем HTML
<div ng-controller="MyController as MC">
    <div ng-controller="item in items" ng-init="MC.someData = 1">
    </div>
</div>

Поскольку теперь вы явно создаете некоторые данные на вашем контроллере "MC", больше нет путаницы. Вы точно знаете, где данные заканчиваются независимо от того, сколько директив или контроллеров вы вложили. Заметьте, что "элемент" все еще находится в области повторителей, но это нормально, поскольку он должен быть внутренним для ретранслятора. Передайте его с помощью функции или, теоретически, ng-init внутри вашего ретранслятора, если вам когда-нибудь понадобится.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню