文档章节

学习 AngularJS (五) scope

刘军兴
 刘军兴
发布于 2015/12/09 14:53
字数 1588
阅读 93
收藏 1
点赞 0
评论 0

继续看 kityminder-editor 部分代码, 一层层进入到 undoRedo.directive.js, 以及对应的模板文件 undoRedo.html,
又看不懂里面的 angularjs 相关代码了, 怎么办?? --- 只能是回学校重新学啊.

幸好买的书到了, 《精通AngularJS》. 但为了弄懂 kityminder 就得学这么多东西, 是不是很复杂? 
万一以后领导/客户说还要改点什么, 一定会更复杂吧...?

将粗看一下部分开始章节, 期望重点了解 scope, directive 概念.

AngularJS 的 MVC 模式

MVC 太知名了, 招聘时年轻的学子们有问你们用不用 MVC 模式, 我都不知道该怎么回答. 看他们表情仿佛是若不用 MVC,
就很落伍很低级 -> 不来. 所以, 还是赶紧学一下什么是 MVC 吧!

MVC (model-view-controller), 是一种架构(architect)模式, 相当抽象. 当前有很多变种和派生 (如 MVP,
MVVM 模式), 开发者有自己对 MVC 的理解并有不同的设计架构. 导致同样的 MVC 名字有不同的架构...

AngularJS 采用注重实效的方式 -> MVW(model-view-whatever) 模式.

书上例子: hello-world 使用 ng-controller:

<div ng-controller='HelloCtrl'>
  <h1>Hello, {{name}}!</h1>
</div>

<script>
function HelloCtrl($scope) {
  $scope.name = 'angular';
}
</script>

要亲自实验一下才放心, 于是写简单网页吧, 看看到底能行不? --- 测试结果: 没通过...

换一下写法, 下面这种才能通过:

<div ng-app='demo' ng-controller='HelloCtrl'>
  <h1>Hello {{ name }}!</h1>
</div>

<script>
angular.module('demo', []) // 必须有一个 module 吗?
  .controller('HelloCtrl', ['$scope', function($scope) { // 必须注册到 module 吗?
    console.log('HelloCtrl() is called, $scope is: ', $scope);
    $scope.name = 'World';
  }]);
</script>

(这样, 看这书是不是前景堪忧啊...) 还是先继续看 scope (作用域)概念吧.

 

作用域 (scope)

AngularJS 中的 $scope 对象是模板的域模型(domain model), 也称为作用域实例 (instance).
通过为其属性赋值, 可以传递数据给模板渲染.

上面的 HelloCtrl 例子中, 输出的 $scope 如下图样子:

 

初看应是一个 Scope 类的实例, 以 $$, $ 开头的属性和方法应该是 angularjs 内部使用的. name 属性是我们添加的.
还注意到有 $id, $parent, $root 属性, 应是构成了 scope 的树结构(层次结构).

书上写向 scope 赋值, 可以传递数据给模板渲染, 那我们来做实验, 手动在 console 中输入语句为 $scope.name 赋新值,
看看能发生什么...?  --- 答案是: 没变化. 这意味着什么?

既然 $scope 对象是模板 (对应 view 吗?) 的域模型 (对应 model 吗?), ... 那么就有了 M&V of MVC 了吗?

作用域 (scope) 可以加入与模板相关的数据(data)和提供相关的功能(function). 例子, 用函数 getName() 替代
name 属性 (实验通过):

angular... .controller(..., function($scope) {
  $scope.getName = function() {
    return 'World';
  }
});
// 对应模板写作: Hello, {{ getName() }}

证明了啥? 证明 AngularJS expression 能支持调用 $scope 上的函数......

$scope 对象可以精准地控制领域模型 (domain model) 的哪些数据和操作在视图上 (view) 上是有效的.
概念上来说, AngularJS 的作用域 (scopes) 与 MVVM 模式的视图模型 (view-model) 非常相似.

控制器

控制器(controller) 的主要职责是初始化作用域 (scope) 实例 (instance).

可以 1. 属性 在 $scope; 2. 方法 于 $scope, 一般是 UI 相关的行为. 

在初始化 scope instance (View-Model of MVVM) 时, controller 与 ng-init 可以做同样的工作.

实验: 我们即有 ng-init 又有 controller, 会发生什么?

<div ng-controller='HelloCtrl' ng-init='name = "Warlord"' >
  Hello {{ name }}!
</div>
// controller 部分中设置 $scope.name = 'World', 其它不变.

结果显示 Hello Warlord! 这说明了什么?

既然 controller 能用, 则尽量将代码放到 controller 中, 而不是将 js 混在 html 模板中.
书上说控制器就是一个 js 函数, 不需要扩展任何 angularjs 特定的类, 不需要调用特定 angularjs api ...
但我单独写 controller 函数却无法通过实验, 也许我还不太熟悉 angular, 又或者旧版本可以写函数?

模型

AngularJS 的模型 (model) 实际上就是普通的 js 对象. 不需要去扩展任何 angularjs 底层类.

可以使用任何 js 类或对象, 属性也不仅限于原始值 (primitive values).

AngularJS 没有侵略性, 它让模型对象远离框架特定的代码. (请一下此设计)

深入作用域

每个 $scope 都是 Scope 类的实例. (我们上面观察 $scope 对象时可注意到这一点)

作用域层级

问题: controller 函数的参数 $scope 从何而来?
答案是: ng-controller 指令使用 scope 对象的 $new(isolate, parent) 方法创建新的作用域, 传递给 controller 函数.
   angularjs 在新应用启动时自动创建 $rootScope 作为其他所有 scope 的父 scope. (?是否 ng-app 启动一个新应用)

ng-controller 指令是作用域创建 (scope-creating) 指令. 每当 DOM 树中遇到此类指令, 都会创建 Scope 类的
新实例 $scope. 新的 $scope 拥有 $parent 属性, 指向它的父作用域.

由于 DOM 是树结构, 附加在 DOM 上的创建 scope 的指令创建出 scope 树也是不奇怪的.

如重复器(repeater)指令 ng-repeat 会创建子作用域, 看例子:

<div ng-controller='HelloCtrl'>
  <ul>
    <li ng-repeat='i in [2,3,5,7]'>Number is {{ i }}</li>
  </ul>
</div>

页面显示出 2,3,5,7 在一个 ul 中. 查看 html 发现有多个 DOM 元素 class 中含有 ng-scope:

 

按照书上指引, 找到一个 Firefox 的扩展 AngScope - AngularJS 作用域查看器 for Firebug, 在 DOM 元素上右键
点击, 出现菜单 'Inspect Angular Scope', 然后可以查看该元素所属作用域. (启发: 也许还有别的 angular 插件...)
(Chrome 类似扩展为 Batarang)

经过查看会发现一些惊人的事实, body 上的 scope.$id = 1, .parent = null, 这应该是为 demo ng-app 创建的根
作用域. div HelloCtrl ng-controller 的 scope.$id = 2, .parent = scope#1;
每个被重复的 li 都有自己的 scope, $id 对应为 3,4,5,6, 其 .parent = scope#2.
也即每个 li 都创建了一个新的 scope...

而且这些 scope 的 __proto__ 属性也比较怪, 似乎就是其 $parent 的值, 也是一层一层向上直到 null.
这种技术似乎很少看到. 也许我应该多花点时间看看其它 js 库? (可是还有事情要忙, 没时间怎么办?) 

用 Chrome + 扩展 Batarang 查看似乎更方便:

 

从而这里就能明白, 为什么在一个 repeater 里面可以访问到 $index, $first, $last, $even, $odd 等属性的原因了.

(休息一下, 下篇接着学...)

© 著作权归作者所有

共有 人打赏支持
刘军兴
粉丝 54
博文 150
码字总数 226172
作品 0
昌平
【前端】—聊聊我认识的Angular

前言 最近接触的项目前端用到了Angular框架,之前略有耳闻,从vue换到Angular,感觉东西差不多,还是要系统学习的,先来了解下。 正文 1、Angular 的发展 AngularJS 是一款来自Google的前端J...

zt15732625878 ⋅ 05/19 ⋅ 0

再谈angularJS数据绑定机制及背后原理—angularJS常见问题总结

Angular 的数据绑定采用什么机制,详述原理? 脏检查机制。阐释脏检查机制,必须先了解如下问题。 单向绑定(ng-bind) 和 双向绑定(ng-model) 的区别? ng-bind 单向数据绑定($scope ->...

634117608 ⋅ 04/19 ⋅ 0

[Angular Material完全攻略] Day 01 - 开始 & 简介

转载 从Angular第2版正式release后,根据全球最大工程师讨论区StackOverflow的统计,从2016开始的Angular讨论度就不断窜升,甚至超越了React,直到了2017年,甚至摆脱了前一代Angularjs的阴影...

readilen ⋅ 05/21 ⋅ 0

Angular 6.0正式版发布,都有哪些新功能

点击关注异步图书,置顶公众号 每天与你分享IT好书 技术干货 职场知识 在Angular 5发布半年之后,Angular 6在昨天正式发布,那么在这个版本有哪些新功能呢?新版本重点关注工具链以及工具链在...

异步社区 ⋅ 05/08 ⋅ 0

Angular 6正式版发布,都有哪些新功能

在Angular 5发布半年之后,Angular 6在昨天正式发布,那么在这个版本有哪些新功能呢?新版本重点关注工具链以及工具链在 Angular 中的运行速度问题。除此之外,这次更新还包括框架包(@angu...

code_xzh ⋅ 05/05 ⋅ 0

JavaScript MVW 框架 - AngularJS

Angular JS (Angular.JS) 是一组用来开发 Web 页面的框架、模板以及数据绑定和丰富 UI 组件。它支持整个开发进程,提供 Web 应用的架构,无需进行手工 DOM 操作。 AngularJS 很小,只有 60K,...

匿名 ⋅ 2011/01/20 ⋅ 44

[Angular Material完全攻略] Day 02 - 环境设定 & 安装 & Hello World

今天我们将开始正式迈入Angular Material的世界,要学习使用Angular Material打造高品质及高质感的网页,当然要从安装Angular Material套件开始,本篇文章就来介绍基本的Angular Material安装...

readilen ⋅ 05/21 ⋅ 0

初学angular 看到网上有angular js 也有angular2 ,到angular官网发现最近版本是6了,那么现在大家说的angular js到底是什么啊?

初学angular 看到网上有angular js 也有angular2 ,到angular官网发现最近版本是6了,那么现在大家说的angular js到底是什么啊? angular2和现在官网的angular6 就是 angular js 只是版本不同...

Jordan裔 ⋅ 05/19 ⋅ 0

AngularJS 的 Material Design 风格框架 - AngularJS Material

AngularJS Material 是 AngularJS 框架的谷歌 Material Design 标准的实现。AngularJS Material 包含一组丰富的、可重用、经过充分测试并可访问的 UI 组件。 针对 Angular 2 或更高版本的实现...

匿名 ⋅ 05/15 ⋅ 0

Angular 6 服务端渲染之 udao 终章

先介绍下小朋友 udao,首先是一个开源项目,代码足够简单,其次是跟随 Angular 大小版本一起成长的项目,会定期更新所有依赖包以及兼容最新版本的写法 Github 地址也贴出来好多次了:github....

orangexc ⋅ 05/10 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

个人博客的运营模式能否学习TMALL天猫质量为上?

心情随笔|个人博客的运营模式能否学习TMALL天猫质量为上? 中国的互联网已经发展了很多年了,记得在十年前,个人博客十分流行,大量的人都在写博客,而且质量还不错,很多高质量的文章都是在...

原创小博客 ⋅ 54分钟前 ⋅ 0

JavaScript零基础入门——(十一)JavaScript的DOM操作

JavaScript零基础入门——(十一)JavaScript的DOM操作 大家好,欢迎回到我们的JavaScript零基础入门。最近有些同学问我说,我讲的的比书上的精简不少。其实呢,我主要讲的是我在开发中经常会...

JandenMa ⋅ 今天 ⋅ 0

volatile和synchronized的区别

volatile和synchronized的区别 在讲这个之前需要先了解下JMM(Java memory Model :java内存模型):并发过程中如何处理可见性、原子性、有序性的问题--建立JMM模型 详情请看:https://baike.b...

MarinJ_Shao ⋅ 今天 ⋅ 0

深入分析Kubernetes Critical Pod(一)

Author: xidianwangtao@gmail.com 摘要:大家在部署Kubernetes集群AddOn组件的时候,经常会看到Annotation scheduler.alpha.kubernetes.io/critical-pod"="",以表示这是一个关键服务,那你知...

WaltonWang ⋅ 今天 ⋅ 0

原子性 - synchronized关键词

原子性概念 原子性提供了程序的互斥操作,同一时刻只能有一个线程能对某块代码进行操作。 原子性的实现方式 在jdk中,原子性的实现方式主要分为: synchronized:关键词,它依赖于JVM,保证了同...

dotleo ⋅ 今天 ⋅ 0

【2018.06.22学习笔记】【linux高级知识 14.4-15.3】

14.4 exportfs命令 14.5 NFS客户端问题 15.1 FTP介绍 15.2/15.3 使用vsftpd搭建ftp

lgsxp ⋅ 今天 ⋅ 0

JeeSite 4.0 功能权限管理基础(Shiro)

Shiro是Apache的一个开源框架,是一个权限管理的框架,实现用户认证、用户授权等。 只要有用户参与一般都要有权限管理,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户...

ThinkGem ⋅ 昨天 ⋅ 0

python f-string 字符串格式化

主要内容 从Python 3.6开始,f-string是格式化字符串的一种很好的新方法。与其他格式化方式相比,它们不仅更易读,更简洁,不易出错,而且速度更快! 在本文的最后,您将了解如何以及为什么今...

阿豪boy ⋅ 昨天 ⋅ 0

Python实现自动登录站点

如果我们想要实现自动登录,那么我们就需要能够驱动浏览器(比如谷歌浏览器)来实现操作,ChromeDriver 刚好能够帮助我们这一点(非谷歌浏览器的驱动有所不同)。 一、确认软件版本 首先我们...

blackfoxya ⋅ 昨天 ⋅ 0

线性回归原理和实现基本认识

一:介绍 定义:线性回归在假设特证满足线性关系,根据给定的训练数据训练一个模型,并用此模型进行预测。为了了解这个定义,我们先举个简单的例子;我们假设一个线性方程 Y=2x+1, x变量为商...

wangxuwei ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部