Angular(一):Controller中this与$scope的区别与联系

在了解他们的区别之前,首先要理解Controller的初始化过程,对Angular而言,每个Controller都是一个个的构造函数,必须要实例化后才能进行调用,所以,Controller在调用时,已经以new的方式执行过一次(请注意,是以new的方式,并不是直接调用),所以必定会生成一个Controller实例,而且每一个Controller都是不同的实例,绝不会相互干扰,从而此实例也必然会继承构造函数中this绑定的所有属性与方法,请看下面的例子:

<!-- 必须要以as的方式才能获取到此实例 -->
<div class="container" ng-controller="AppCtrl as ac">
    <h2 ng-click="ac.toggle()">{
         
  {ac.username}}</h1>
</div>
<script>
    //  完全可以不使用$scope
    app.controller(AppCtrl, function() {
           
    
        this.username = yiifaa;
        this.toggle = function () {
           
    
            if(this.username == yiifaa) {
                this.username = yiifee
            } else {
                this.username = yiifaa
            }
        }
    });
</script>

在上面的HTML代码中,必须以限定名的方式使用Controller的属性与方法,为什么呢?因为它们没有定义在$scope中啊,就是这么简单。

从而,我们可以很容易写出基于$scope的代码,如下:

<div class="container" ng-controller="AppCtrl">
    <h2 ng-click="toggle()">{
          
   {
          
   username}}</h1>
</div>
<script>
    //  完全可以不使用this,这里的this是指构造函数的上下文,并非this这个单词
    app.controller(AppCtrl, function($scope) {
            
     
        $scope.username = yiifaa;
        $scope.toggle = function () {
            
     
            //  因为是方法作用域,这里的this指向$scope
            if(this.username == yiifaa) {
                this.username = yiifee
            } else {
                this.username = yiifaa
            }
        }
    });
</script>

区别在哪里?一眼就可以出来,不需要对象的限定名了。

从上面的代码可以看出,它们其实没什么联系,如果非要说有的话,那么它们都可以在同一个构造函数中互相访问,$scope是这个函数的形参,this是这个函数的上下文,所以它们绝对不是同一个对象(似乎应该说三遍比较好)。

在this中引用$scope

在第一种方案中引用$scope,因为依赖于HTML定义中Controller的实例名称,所以灵活性,一般较少使用,如下:

this.toggle = function () {
          
   
    //  通过$scope依旧可以获取此对象
    alert($scope.ac.username)
    if(this.username == 李浩) {
        this.username = 王菲
    } else {
        this.username = 李浩
    }
}

在$scope中获取this

这充分利用了Controller实例的唯一性,将方法定义在 scope中,属性定义在this中,大幅度简化了 scope的复杂度,从而在HTML中引用时,属性必须加上实例限定名,这也是官方的示例,代码示例如下:

app.controller(AppCtrl, function($scope) {
        var that = this;
        that.username = yiifaa;
        $scope.toggle = function () {
            //  因为是方法作用域,这里的this指向$scope
            if(that.username == yiifaa) {
                that.username = yiifee
            } else {
                that.username = yiifaa
            }
        }
});

结论

Controller中的this与$scope都可以存储域数据信息,无论哪种方案都可以轻松解决域数据与视图的关联性问题,但最好不要域数据分散存储两个对象中。

经验分享 程序员 微信小程序 职场和发展