'this' vs $ scope в контроллерах AngularJS

на раздел" Создание компонентов " домашней страницы AngularJS есть такой пример:

controller: function($scope, $element) {
  var panes = $scope.panes = [];
  $scope.select = function(pane) {
    angular.forEach(panes, function(pane) {
      pane.selected = false;
    });
    pane.selected = true;
  }
  this.addPane = function(pane) {
    if (panes.length == 0) $scope.select(pane);
    panes.push(pane);
  }
}

обратите внимание, как select метод добавляется к $scope, а addPane метод добавляется к this. Если я изменю его на $scope.addPane разрывы код.

в документации говорится, что на самом деле есть разница, но она не упоминает, в чем разница:

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

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

7 ответов


"как this и $scope работа в контроллерах AngularJS?"

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

  • this
    • когда вызывается функция конструктора контроллера,this контроллер.
    • когда функция определена на

причина "addPane" назначается этому из-за


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


Я рекомендую вам прочитать следующий пост: AngularJS:" контроллер как "или"$scope"?

Он очень хорошо описывает преимущества использования "контроллера как" для выставления переменных над "$ scope".

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

поэтому, на мой взгляд, из-за проблемы переменных, обсуждаемой в сообщении, лучше просто используйте метод" контроллер как", а также применяйте его к методам.


в этом курсе (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>

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

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

return angular.extend($scope, this);

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

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


$scope имеет другой " это "контроллер " это".Таким образом, если вы поставите консоль.журнал (это) внутри контроллера он дает вам объект (контроллер) и это.addPane () добавляет метод addPane к объекту контроллера. Но $scope имеет другую область, и весь метод в ее области должен быть доступен $scope.methodName (). this.methodName() внутренний регулятор значит добавить метос внутри объекта регулятора.$scope.functionName() в HTML и внутри

$scope.functionName(){
    this.name="Name";
    //or
    $scope.myname="myname"//are same}

вставьте этот код в Редактор и откройте консоли увидеть...

 <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>this $sope vs controller</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js"></script>
    <script>
        var app=angular.module("myApp",[]);
app.controller("ctrlExample",function($scope){
          console.log("ctrl 'this'",this);
          //this(object) of controller different then $scope
          $scope.firstName="Andy";
          $scope.lastName="Bot";
          this.nickName="ABot";
          this.controllerMethod=function(){

            console.log("controllerMethod ",this);
          }
          $scope.show=function(){
              console.log("$scope 'this",this);
              //this of $scope
              $scope.message="Welcome User";
          }

        });
</script>
</head>
<body ng-app="myApp" >
<div ng-controller="ctrlExample">
       Comming From $SCOPE :{{firstName}}
       <br><br>
       Comming from $SCOPE:{{lastName}}
       <br><br>
       Should Come From Controller:{{nickName}}
       <p>
            Blank nickName is because nickName is attached to 
           'this' of controller.
       </p>

       <br><br>
       <button ng-click="controllerMethod()">Controller Method</button>

       <br><br>
       <button ng-click="show()">Show</button>
       <p>{{message}}</p>

   </div>

</body>
</html>