"Как this
и $scope
работают в контроллерах AngularJS?"
Краткий ответ:
this
- When the controller constructor function is called,
this
is the controller.
- Когда вызывается функция, определенная для объекта
$scope
, this
является «областью действия, когда функция была вызвана». Это может быть (а может и не быть!) $scope
, на котором определена функция. Таким образом, внутри функции this
и $scope
могут не совпадать.
$scope
- Every controller has an associated
$scope
object.
- Функция контроллера (конструктора) отвечает за установку свойств модели и функций / поведения связанных с ней
$scope
.
- Только методы, определенные в этом объекте
$scope
(и объекты родительской области, если используется прототипное наследование), доступны из HTML / представления. Например, из ng-click
, фильтры и т. Д.
Длинный ответ:
Функция контроллера - это функция конструктора JavaScript. Когда функция конструктора выполняется (например, при загрузке представления), this
(т.е. «контекст функции») устанавливается в объект контроллера. Итак, в функции конструктора контроллера "вкладки" при создании функции addPane
this.addPane = function(pane) { ... }
он создается в объекте контроллера, а не в $ scope. Представления не могут видеть функцию addPane - они имеют доступ только к функциям, определенным в $ scope. Другими словами, в HTML это не сработает:
<a ng-click="addPane(newPane)">won't work</a>
После выполнения функции конструктора контроллера tabs мы имеем следующее:
![после функции конструктора контроллера вкладок](https://i.stack.imgur.com/PUMuU.png)
Пунктирная черная линия указывает на прототипное наследование - изолированная область видимости прототипически наследуется от Scope. (Он не наследуется прототипом от той области действия, в которой директива была встречена в HTML.)
Теперь функция ссылки директивы панели хочет взаимодействовать с директивой tabs (что на самом деле означает, что она должна каким-то образом влиять на вкладки, изолирующие $ scope). Можно использовать события, но другой механизм - это директива pane require
для контроллера вкладок. (Похоже, что для директивы pane require
области вкладок $ не существует механизма.)
Итак, возникает вопрос: если у нас есть доступ только к контроллеру вкладок, как мы можем получить доступ к вкладкам, изолирующим $ scope (что мы действительно хотим)?
Что ж, красная пунктирная линия - это ответ. «Область действия» функции addPane () (здесь я имею в виду область / закрытие функции JavaScript) дает функции доступ к вкладкам, изолирующим $ scope. То есть addPane () имеет доступ к «вкладкам IsolateScope» на диаграмме выше из-за закрытия, которое было создано при определении addPane (). (Если бы вместо этого мы определили addPane () в объекте tabs $ scope, директива pane не имела бы доступа к этой функции, и, следовательно, у нее не было бы возможности взаимодействовать с tabs $ scope.)
Чтобы ответить на другую часть вашего вопроса: how does $scope work in controllers?
:
В функциях, определенных в $ scope, this
устанавливается в «$ scope в действии, где / когда функция была вызвана». Предположим, у нас есть следующий HTML:
<div ng-controller="ParentCtrl">
<a ng-click="logThisAndScope()">log "this" and $scope</a> - parent scope
<div ng-controller="ChildCtrl">
<a ng-click="logThisAndScope()">log "this" and $scope</a> - child scope
</div>
</div>
И ParentCtrl
(Исключительно) имеет
$scope.logThisAndScope = function() {
console.log(this, $scope)
}
Щелчок по первой ссылке покажет, что this
и $scope
одинаковы, поскольку «действующая область действия при вызове функции» - это область, связанная с ParentCtrl
.
Щелчок по второй ссылке покажет, что this
и $scope
не одинаковы, так как «действующая область действия при вызове функции» - это область, связанная с ChildCtrl
. Итак, здесь this
установлен на ChildCtrl
's $scope
. Внутри метода $scope
по-прежнему является $ scope ParentCtrl
.
Fiddle
Я стараюсь не использовать this
внутри функции, определенной в $ scope, так как становится непонятно, какая $ scope затронута, особенно учитывая, что ng-repeat, ng-include, ng-switch и директивы могут создавать свои собственные дочерние области .
person
Mark Rajcok
schedule
05.01.2013