"Как работает this
и $scope
работает в контроллерах AngularJS?"
Краткий ответ :
this
- Когда вызывается функция конструктора контроллера,
this
это контроллер.
- Когда
$scope
вызывается функция, определенная для объекта, this
это «область действия, когда функция была вызвана». Это может (или не может!) Быть тем $scope
, на котором определена функция. Итак, внутри функции this
и не$scope
могут быть одинаковыми.
$scope
- Каждый контроллер имеет связанный
$scope
объект.
- Функция контроллера (конструктора) отвечает за установку свойств модели и функций / поведения ее связанного
$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» имеем следующее:
Пунктирная черная линия указывает на наследование прототипа - область изолята, прототипно наследуемая от Scope . (Он не наследуется по прототипу от области действия, в которой директива встречалась в HTML.)
Теперь функция link директивы pane хочет связаться с директивой tabs (что на самом деле означает, что она должна каким-то образом влиять на вкладки, изолируя $ scope). События могут быть использованы, но другой механизм должен иметь директиву pane require
контроллера tabs. (По-видимому, не существует механизма для директивы панели для require
вкладок $ scope.)
Итак, напрашивается вопрос: если у нас есть доступ только к контроллеру вкладок, как нам получить доступ к вкладкам, изолирующим $ scope (что мы действительно хотим)?
Ну, красная пунктирная линия - это ответ. «Область» функции addPane () (я имею в виду область / замыкания функции JavaScript здесь) дает функции доступ к вкладкам, изолирующим область $. То есть addPane () имеет доступ к «вкладкам IsolateScope» на диаграмме выше из-за замыкания, которое было создано при определении addPane (). (Если бы мы вместо этого определили addPane () на объекте $ scope вкладок, директива pane не будет иметь доступа к этой функции, и, следовательно, не будет иметь возможности связаться с вкладками $ scope.)
Чтобы ответить на другую часть вашего вопроса how does $scope work in controllers?
:
Внутри функций, определенных в $ scope, this
устанавливается значение «действительная область $, где / когда была вызвана функция». Предположим, у нас есть следующий 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
все еще находится ParentCtrl
область действия $.
скрипка
Я стараюсь не использовать this
внутри функции, определенной в $ scope, так как становится непонятно, какая область $ затрагивается, особенно с учетом того, что ng-repeat, ng-include, ng-switch и директивы могут создавать свои собственные дочерние области.