Как использовать область действия в AngularJS [duplicate]

Иногда эта ошибка возникает, когда дисковое пространство меньше. так что проверьте пространство вашего компьютера, где размещается jenkins. :)

966
задан Peter Mortensen 22 October 2015 в 17:13
поделиться

7 ответов

«Как this и $scope работают в контроллерах AngularJS?»

Короткий ответ:

  • this Когда вызывается функция конструктора контроллера, this - контроллер. Когда вызывается функция, определенная на объекте $scope, this является «областью действия, когда функция была вызвана». Это может (или не может быть!) Быть $scope, что функция определена. Таким образом, внутри функции this и $scope могут быть не одинаковыми.
  • $scope Каждый контроллер имеет ассоциированный объект $scope. Функция контроллера (конструктора) отвечает за настройку свойств модели и функций / поведения на ее ассоциированном $scope. Только методы, определенные на этом объекте $scope (и родительские объекты области, если прототипическое наследование находится в игре) доступны из HTML / view. Например, из ng-click, фильтров и т. Д.

Длинный ответ:

Функция контроллера - это функция JavaScript-конструктора. Когда функция конструктора выполняется (например, при загрузке представления), this (то есть «контекст функции») устанавливается в объект контроллера. Таким образом, в функции конструктора контроллера «tabs», когда создается функция addPane

this.addPane = function(pane) { ... }

, она создается на объекте контроллера, а не на $ scope. Представления не видят функцию addPane - они имеют доступ только к функциям, определенным в области $ scope. Другими словами, в HTML это не сработает:

<a ng-click="addPane(newPane)">won't work</a>

После выполнения функции конструктора контроллера «tabs» мы имеем следующее:

after tabs controller constructor function [/g4]

Пунктирная черная линия указывает на прототипное наследование - объем выделения, который прототипически наследуется из Scope . (Это не прототипно наследует область действия, в которой эта директива встречается в HTML.)

Теперь функция ссылки директивы панели хочет связываться с директивой tabs (что на самом деле означает, что она должна влиять вкладки каким-то образом изолируют $ scope). Можно использовать события, но другим механизмом является наличие указателя панели require контроллера табуляции. (Кажется, нет механизма для директивы панели для require вкладки $ scope.)

Итак, это ставит вопрос: если у нас есть только доступ к контроллеру вкладок, как мы получаем доступ на вкладках изолировать $ scope (что мы действительно хотим)?

Ну, красная пунктирная линия - это ответ. Функция «scope» функции addPane () (я имею в виду область действия / закрытие функции JavaScript здесь) дает функции доступа к вкладкам изолировать $ scope. I.e., addPane () имеет доступ к «вкладкам IsolateScope» на диаграмме выше из-за закрытия, которое было создано, когда была определена addPane (). (Если мы вместо этого определяем addPane () в объекте облака tabs $, директива панели не будет иметь доступа к этой функции, и, следовательно, у нее не будет возможности связываться с областью вкладок $.)

To ответьте на другую часть вашего вопроса: 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 (Solely) имеет

$scope.logThisAndScope = function() {
    console.log(this, $scope)
}

. Щелчок по первой ссылке показывает, что this и $scope совпадают, поскольку « область действия, когда функция была вызвана », - это область, связанная с ParentCtrl.

Щелчок по второй ссылке показывает this и $scope не совпадают, так как « область действия, когда функция была вызвана », - это область, связанная с ChildCtrl. Итак, здесь this установлено значение ChildCtrl $scope. Внутри метода $scope по-прежнему является [scope] ParentCtrl.

Fiddle

Я пытаюсь не использовать this внутри функция, определенная в области $ scope, так как она запутывает, на какой объект влияет область видимости, особенно учитывая, что ng-repeat, ng-include, ng-switch и директивы могут создавать собственные дочерние области.

950
ответ дан Andrew Tobilko 18 August 2018 в 17:21
поделиться
  • 1
    @tamakisquare, я считаю, что выделенный вам полужирный текст относится к тому, когда вызывается функция конструктора контроллера, т. е. когда создается контроллер = связанный с $ scope. Это не применяется позже, когда произвольный код JavaScript вызывает метод, определенный в объекте $ scope. – Mark Rajcok 19 February 2013 в 22:04
  • 2
    Обратите внимание, что теперь можно вызвать функцию addPane () непосредственно в шаблоне, назвав контроллер: «MyController as myctrl»; а затем myctrl.addPane (). См. docs.angularjs.org/guide/concepts#controller – Christophe Augier 29 November 2013 в 23:44
  • 3
    Слишком сложная сложность. – Inanc Gumus 7 June 2014 в 09:33
  • 4
    Это очень информативный ответ, но когда я вернулся с практической проблемой (, как вызывать $ scope. $ Apply () в методе контроллера, определяемом с помощью 'this' ), я не смог его обработать , Поэтому, хотя это еще полезный ответ, я нахожу «присущую сложность». озадачивает. – dumbledad 15 December 2014 в 19:10
  • 5
    Javascript - много веревки [повесить себя]. – AlikElzin-kilaka 1 June 2015 в 07:09
0
ответ дан Aniket Jha 18 August 2018 в 17:21
поделиться

Я просто прочитал довольно интересное объяснение различий между ними и растущее предпочтение прикреплять модели к контроллеру и псевдоним контроллера для привязки моделей к представлению. http://toddmotto.com/digging-into-angulars-controller-as-syntax/ - статья. Он не упоминает об этом, но при определении директив, если вам нужно поделиться чем-то между несколькими директивами и не хотеть службы (есть законные случаи, когда услуги - это хлопот), тогда прикрепите данные к контроллеру родительской директивы. Служба $ scope предоставляет множество полезных вещей, $ watch является наиболее очевидным, но если все, что вам нужно, привязать данные к представлению, используя простой контроллер и «контроллер как» в шаблоне, отлично и, возможно, предпочтительнее.

26
ответ дан Derek 18 August 2018 в 17:21
поделиться

Предыдущие версии Angular (pre 1.0 RC) позволили вам использовать это взаимозаменяемо с методом $ scope, но это уже не так. Внутри методов, определенных в области действия this и $ scope, взаимозаменяемы (угловое задает это значение в $ scope), но не внутри внутри вашего конструктора контроллера.

Чтобы вернуть это поведение (кто-нибудь знает почему это было изменено?) вы можете добавить:

return angular.extend($scope, this);

в конце вашей функции контроллера (при условии, что $ scope был введен в эту функцию контроллера).

У этого есть хороший эффект наличия доступа к родительской области через объект контроллера, который вы можете получить в дочернем с require: '^myParentDirective'

3
ответ дан Kamil Szot 18 August 2018 в 17:21
поделиться

Я рекомендую вам прочитать следующее сообщение: http://codetunnel.io/angularjs-controller-as-or-scope/

он очень хорошо описывает преимущества использования «Controller as» для отображения переменных над «$ scope».

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

Итак, по моему мнению, из-за проблемы с переменными, обсуждаемой в сообщении, лучше просто использовать технику «Контроллер как», а также применить ее к методам.

15
ответ дан Liran Brimer 18 August 2018 в 17:21
поделиться

Причиной «addPane» назначается это из-за директивы <pane>.

Директива pane делает require: '^tabs', которая помещает объект контроллера таблеток из родительской директивы в функция ссылки.

addPane присваивается this, так что функция ссылки pane может ее видеть. Затем в функции pane link addPane является просто свойством контроллера tabs, и это всего лишь tabsControllerObject.addPane. Таким образом, функция связывания указателей панели может получить доступ к объекту контроллера таблеток и, следовательно, получить доступ к методу addPane.

Надеюсь, что мои объяснения достаточно ясны. Это трудно объяснить.

50
ответ дан Mon Calamari 18 August 2018 в 17:21
поделиться
  • 1
    – Alexei Boronine 24 July 2012 в 01:23
  • 2
    По-видимому, родительская область не передается в функцию lnk из-за желания поддерживать «повторно используемые компоненты», которые не должны случайно считывать или изменять данные в родительской области. & Quot; Но если директива действительно хочет / нуждается в чтении или изменении НЕКОТОРЫХ СПЕЦИФИЧЕСКИХ данных в родительской области (например, в директиве 'pane'), это требует некоторых усилий: «потребовать» контроллер, где находится желаемая родительская область, затем определить метод на этом контроллере (используйте 'this' not $ scope) для доступа к конкретным данным. Поскольку желаемая родительская область не вводится в функцию lnk, я полагаю, что это единственный способ сделать это. – Mark Rajcok 13 September 2012 в 04:42
  • 3
    Эй, отметьте, на самом деле проще изменить область действия директивы. Вы можете просто использовать функцию ссылки jsfiddle.net/TuNyj – Andrew Joslin 13 September 2012 в 14:28
  • 4
    Спасибо @ Энди за скрипку. В вашей скрипте директива не создает новую область видимости, поэтому я вижу, как функция ссылки может напрямую обращаться к области контроллера здесь (поскольку существует только одна область). В директивах tabs и pane используются изолированные области (т. Е. Создаются новые дочерние области, которые не прототипически наследуются от родительской области). Для случая разметки изоляции, кажется, что определение метода на контроллере (с использованием «этого») является единственным способом разрешить другой дирекции получить (косвенный) доступ к другой (изолированной) области. – Mark Rajcok 1 January 2013 в 18:56

В этом курсе ( https://www.codeschool.com/courses/shaping-up-with-angular-js ) они объясняют, как использовать «это» и многие другие вещи.

Если вы добавите метод к контроллеру через этот метод, вы должны вызвать его в представлении с именем контроллера «точка» вашего свойства или метода.

Например, используя ваш контроллер в представлении вы можете иметь такой код:

    <div data-ng-controller="YourController as aliasOfYourController">

       Your first pane is {{aliasOfYourController.panes[0]}}

    </div>
15
ответ дан Sandro 18 August 2018 в 17:21
поделиться
  • 1
    Пройдя курс, меня сразу же смутил код, используя $scope, поэтому спасибо, что упомянул об этом. – Matt Montag 11 December 2014 в 04:24
  • 2
    В этом курсе вообще не упоминается $ scope, они просто используют as и this, и как это может помочь объяснить разницу? – dumbledad 11 December 2014 в 15:52
  • 3
    Мой первый контакт с Angular был из упомянутого курса, и поскольку $scope никогда не упоминался, я научился использовать только this в контроллерах. Проблема в том, что когда вы начинаете обрабатывать обещания в своем контроллере, у вас есть много проблем с ссылками на this, и вам нужно начать делать такие вещи, как var me = this, чтобы ссылаться на модель в this из функции возврата обещания , Поэтому из-за этого я все еще очень смущен тем, какой метод мне следует использовать, $scope или this. – Bruno Finger 11 March 2015 в 12:12
  • 4
    @BrunoFinger К сожалению, вам понадобятся var me = this или .bind(this) всякий раз, когда вы выполняете обещания, или другие вещи, связанные с закрытием. Это не имеет никакого отношения к Угловому. – Dzmitry Lazerka 18 March 2016 в 06:28
  • 5
    – Bruno Finger 21 March 2016 в 10:48
Другие вопросы по тегам:

Похожие вопросы: