'this' vs $scope in AngularJS controllers

后端 未结 7 1504
逝去的感伤
逝去的感伤 2020-11-21 05:18

In the \"Create Components\" section of AngularJS\'s homepage, there is this example:

controller: function($scope, $element) {
  var panes = $scope.panes = [         


        
相关标签:
7条回答
  • 2020-11-21 05:25

    I recommend you to read the following post: AngularJS: "Controller as" or "$scope"?

    It describes very well the advantages of using "Controller as" to expose variables over "$scope".

    I know you asked specifically about methods and not variables, but I think that it's better to stick to one technique and be consistent with it.

    So for my opinion, because of the variables issue discussed in the post, it's better to just use the "Controller as" technique and also apply it to the methods.

    0 讨论(0)
  • 2020-11-21 05:30

    In this course(https://www.codeschool.com/courses/shaping-up-with-angular-js) they explain how to use "this" and many other stuff.

    If you add method to the controller through "this" method, you have to call it in the view with controller's name "dot" your property or method.

    For example using your controller in the view you may have code like this:

        <div data-ng-controller="YourController as aliasOfYourController">
    
           Your first pane is {{aliasOfYourController.panes[0]}}
    
        </div>
    
    0 讨论(0)
  • 2020-11-21 05:31

    $scope has a different 'this' then the controller 'this'.Thus if you put a console.log(this) inside controller it gives you a object(controller) and this.addPane() adds addPane Method to the controller Object. But the $scope has different scope and all method in its scope need to be accesed by $scope.methodName(). this.methodName() inside controller means to add methos inside controller object.$scope.functionName() is in HTML and inside

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

    Paste this code in your editor and open console to see...

     <!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>
    
    0 讨论(0)
  • 2020-11-21 05:38

    Previous versions of Angular (pre 1.0 RC) allowed you to use this interchangeably with the $scope method, but this is no longer the case. Inside of methods defined on the scope this and $scope are interchangeable (angular sets this to $scope), but not otherwise inside your controller constructor.

    To bring back this behaviour (does anyone know why was it changed?) you can add:

    return angular.extend($scope, this);
    

    at the end of your controller function (provided that $scope was injected to this controller function).

    This has a nice effect of having access to parent scope via controller object that you can get in child with require: '^myParentDirective'

    0 讨论(0)
  • 2020-11-21 05:40

    I just read a pretty interesting explanation on the difference between the two, and a growing preference to attach models to the controller and alias the controller to bind models to the view. http://toddmotto.com/digging-into-angulars-controller-as-syntax/ is the article.

    NOTE: The original link still exists, but changes in formatting have made it hard to read. It's easier to view in the original.

    He doesn't mention it but when defining directives, if you need to share something between multiple directives and don't want a service (there are legitimate cases where services are a hassle) then attach the data to the parent directive's controller.

    The $scope service provides plenty of useful things, $watch being the most obvious, but if all you need to bind data to the view, using the plain controller and 'controller as' in the template is fine and arguably preferable.

    0 讨论(0)
  • 2020-11-21 05:42

    The reason 'addPane' is assigned to this is because of the <pane> directive.

    The pane directive does require: '^tabs', which puts the tabs controller object from a parent directive, into the link function.

    addPane is assigned to this so that the pane link function can see it. Then in the pane link function, addPane is just a property of the tabs controller, and it's just tabsControllerObject.addPane. So the pane directive's linking function can access the tabs controller object and therefore access the addPane method.

    I hope my explanation is clear enough.. it's kind of hard to explain.

    0 讨论(0)
提交回复
热议问题