Angular this vs $scope

this vs $scope

------------------------------------------------------------------------------

‘this‘ vs $scope in AngularJS controllers

How does this and $scope work in AngularJS controllers?

Short answer:

  • this

    • When the controller constructor function is called, this is the controller.(当控制器构造函数被“调用”时,this就是控制器函数)
    • When a function defined on a $scope object is called, this is the "scope in effect when the function was called". This may (or may not!)(this可能是也可不能不是$scope) be the $scope that the function is defined on. So, inside the function, this and $scope may not be the same.
  • $scope
    • Every controller has an associated $scope object(每个控制器都有一个与其相关联的$scope).
    • A controller (constructor) function is responsible for setting model properties and functions/behaviour on its associated $scope.
    • Only methods defined on this $scope object (and parent scope objects, if prototypical inheritance is in play) are accessible from the HTML/view. E.g., from ng-click, filters, etc.

Long answer:

A controller function is a JavaScript constructor function.(控制器函数就是一个普普通通地构造器函数)

When the constructor function executes (e.g., when a view loads), this (i.e., the "function context") is set to the controller object. So in the "tabs" controller constructor function, when the addPane function is created

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

it is created on the controller object, not on $scope. Views cannot see the addPane function -- they only have access to functions defined on $scope. In other words, in the HTML, this won‘t work:

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

After the "tabs" controller constructor function executes, we have the following:

The dashed black line indicates prototypal inheritance -- an isolate scope prototypically inherits from Scope. (It does not prototypically inherit from the scope in effect where the directive was encountered in the HTML.)

Now, the pane directive‘s link function wants to communicate with the tabs directive (which really means it needs to affect the tabs isolate $scope in some way). Events could be used, but another mechanism is to have the pane directive require the tabs controller. (There appears to be no mechanism for the pane directive to require the tabs $scope.)

So, this begs the question: if we only have access to the tabs controller, how do we get access to the tabs isolate $scope (which is what we really want)?

Well, the red dotted line is the answer. The addPane() function‘s "scope" (I‘m referring to JavaScript‘s function scope/closures here) gives the function access to the tabs isolate $scope. I.e., addPane() has access to the "tabs IsolateScope" in the diagram above because of a closure that was created when addPane() was defined. (If we instead defined addPane() on the tabs $scope object, the pane directive would not have access to this function, and hence it would have no way to communicate with the tabs $scope.)

To answer the other part of your question: how does $scope work in controllers?:

Within functions defined on $scope, this is set to "the $scope in effect where/when the function was called". Suppose we have the following 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>

And the ParentCtrl (Solely) has

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

Clicking the first link will show that this and $scope are the same, since "the scope in effect when the function was called" is the scope associated with the ParentCtrl.

Clicking the second link will reveal this and $scope are not the same, since "the scope in effect when the function was called" is the scope associated with the ChildCtrl. So here, this is set to ChildCtrl‘s $scope. Inside the method, $scope is still the ParentCtrl‘s $scope(点击子控制器时,this指向了子控制器(this的指向问题),$scope仍旧指向了父控制器).

I try to not use this inside of a function defined on $scope, as it becomes confusing which $scope is being affected, especially considering that ng-repeat, ng-include, ng-switch, and directives can all create their own child scopes.

--------------------------------------------------------------------------

Angular this vs $scope

最近在Angular项目中遇到关于controller内使用$scope&this 暴露数据的问题,下面来分析一下:

“controller as” 是Angular在1.2版本后新增的语法,我将从引用方式,作用范围,对象对比三个方面做两者的比较:

一、引用方式:

1) $scope 只需要在注入中声明,后面就可以直接在附加数据对象:

controller:

function ACtrl($scope) {

$scope.test = "一个例子"; //在$scope对象中加入test

}

html:

<div ng-controller="ACtrl">

{{test}}

</div>

2) this 则采用了controller as(需要版本为ng 1.2+)写法:

controller:

function BCtrl() {

var vm = this;

this.test = "一个例子"; //在this对象中加入test

}

html:

<!-- vm为自己为当前控制器作的一个简略记号,也可以写作 BCtrl as b,

后面变量便可以在b中引出 如b.test -->

<div ng-controller="BCtrl as vm">

{{vm.test}}

</div>

二、作用范围:

1) $scope 中的变量或数据对象我们可以全部拿到,并且上级控制器中的变量也可以在下级控制器中被获取到:

controller:

function ParentCtrl($scope) {

$scope.test = "测试";

$scope.cover ="覆盖测试";

}

function ChildCtrl($scope) {

$scope.cover ="子覆盖测试";

var test = $scope.test; //“测试”

}

html:

<div ng-controller="ParentCtrl">

<p>Parent-test : {{test}}</p>

<p>Parent-cover : {{cover}}</p>

<div ng-controller="ChildCtrl">

<p>Child-test : {{test}}</p>

<p>Child-cover : {{cover}}</p>

</div>

</div>

我在父控制器ParentCtrl中声明的test变量并未在子控制器ChildCtrl中做声明,而在ChildCtrl作用范围内的Child-test 中,test却输出了”测试”;基于此我再做了一次覆盖测试,检测结果显示,当父子控制器同时存在相同的变量时, 父子控制器各自范围内的值不会被覆盖;

2) this 中的变量则只适用于当前控制器:

controller:

function ParentCtrl($scope) {

var vm = this;

vm.test = "测试";

vm.cover ="覆盖测试";

}

function ChildCtrl($scope) {

var vm = this;

vm.cover ="子覆盖测试";

}

html:

<div ng-controller="ParentCtrl as parent">

<p>Parent-test : {{parent.test}}</p>

<p>Parent-cover : {{parent.cover}}</p>

<div ng-controller="ChildCtrl as child">

<p>Child-test : {{child.test}}</p>

<p>Child-cover : {{child.cover}}</p>

</div>

<div ng-controller="ChildCtrl as parent">

<p>Child-test : {{parent.test}}</p>

<p>Child-cover : {{parent.cover}}</p>

</div>

</div>

在使用this的时候,各层级变量的命名空间是平行的状态,模板html中只可以拿到当前控制器下声明的变量。

三、对象对比:

controller:

function CCtrl($scope) {

var vm = this;

$scope.logThisAndScope = function() {

console.log(vm === $scope)

}

}

vm与$scope实际上是不相等的,在console中我们可以看到

vm: Constructor;

$scope: $get.Scope.$new.Child;

而在$scope中又包含了一个变量vm: Constructor

所以,$scope和this的实际关系,实际结构是

$scope: {

...,

vm: Constructor,

...

}

那么我们可以整理如下:

$scope 当控制器在写法上形成父子级关系时,子级没有的变量或方法父级会自动强加在子级身上,子级可以任意获取到当前父级的变量或方法,该种形式是不可逆的,即父级无法通过$scope获取到子级的任意变量或方法。

this      则像一个独立的个体,所有东西都是由自己管理,也就不存在父子级变量混淆关系了。

那数据共享该如何进行呢?数据业务逻辑我觉得还是交给更专业的service来处理吧。

两种方式其实在性能上并无优劣之分,只有代码习惯的选择。

这或许可以取决于我们观察的角度,其实可以理解为私用跟公用的区别!

时间: 2024-10-10 07:14:29

Angular this vs $scope的相关文章

angular中的scope

angular.element($0).scope() 什么是scope? scope是一个refer to the application model的object.它是一个expression的执行上下文context.scopes模仿DOM的层次模型也有层次关系.Scopes可以watch一个expression也可以propagate events. scope特性 scope提供API $watch来观察模型的变化 scope提供API $apply来传播angular外部世界(比如c

Angular 中得 scope 作用域梳理

$scope 的使用贯穿整个 Angular App 应用,它与数据模型相关联,同时也是表达式执行的上下文.有了 $scope 就在视图和控制器之间建立了一个通道,基于作用域视图在修改数据时会立刻更新 $scope,同样的 $scope 发生改变时也会立刻重新渲染视图. 有了 $scope 这样一个桥梁,应用的业务代码可以都在 controller 中,而数据都存放在controller 的 $scope 中. $rootScope Angular 应用启动并生成视图时,会将根 ng-app 元

秒味课堂Angular js笔记------$scope.$watch和$scope.$apply

$scope.$watch(watchFn , watchAction , deepWatch) 其中,watchFn是带有angular表达式或函数字符串: watchAction是一个函数或者表达式,当watchFn发生变化时调用,如果是函数,其签名是function(newValue, oldValue, scope): deepWatch如果是ture,则会检查被监控对象的每一个属性是否发生了变化. <script type="application/javascript"

angular自定义指令scope属性学习笔记

指令在angular项目中的应用非常频繁,当它自带的指令不能满足我们的需求时,我们就需要自定义指令: 在angular,作用域是一个很重要的概念.同样的,要定义一个指令,我们也需要设置他的sope: angular为自定义指令提供了三种scope:①不创建独立的作用域,直接使用父作用域(false):②创建一个继承自它的父级作用域的独立作用域(true):③创建一个完全与外部隔离的作用域({}):

Angular中directive——scope选项与绑定策略,这个也经常迷惑的。

开门见山地说,scope:{}使指令与外界隔离开来,使其模板(template)处于non-inheriting(无继承)的状态,当然除非你在其中使用了transclude嵌入,这点之后的笔记会再详细记录的.但是这显然不符合实际开发中的需求,因为实际上,我们经常想要我们的指令能够在特定的情况下与外界进行数据上的交互,这就需要借助绑定策略之手了. 大家知道,当scope选项写为scope:{}这种形式的时候,就已经为指令生成了隔离作用域,现在,我们来看看绑定策略的三种形式:& .= .@. 首先是

Angular 从DOM中获取scope

节选官方文档: 原文:https://docs.angularjs.org/guide/scope Retrieving Scopes from the DOM. Scopes are attached to the DOM as $scope data property, and can be retrieved for debugging purposes. (It is unlikely that one would need to retrieve scopes in this way

angular的$scope的使用

1. 可以在scope中直接使用 // 监听日期变化 $scope.$watch('vaFilter.startEffectiveDate', function(newDate, oldDate, scope){ if (!angular.isUndefined(newDate)) { $scope.fromDate = newDate; } }); 2. 可以直接监视angular以外的js变量 angular.module('myModule', []).controller('MyCtrl

bootstrap 有些控件需要调用锚点,会与angular 路由 冲突

最简单的方法 就是 在 #号前加/, 但有人说 在服务器上回失效,也不知道是什么原理.慎用 最靠谱的方法 就 是 使用bootstrap中的js控制控件, 比如轮播图的上一页 下一页,就可以在 angular的控制器中添加这两个方法. bootstrap的轮播图部分代码 <!-- Controls --> <a class="left carousel-control" href="" ng-click="prev()" rol

2.angular MVC

AngularJs的MVC全部借助于$scope(作用域)实现 1.ng指令 <!doctype html> <html ng-app> <head> <meta charset="utf-8"> </head> <body> <div ng-controller="CommonController"> <div ng-controller="Controller1&