AngularJS in Action读书笔记1——扫平一揽子专业术语

时间:2022-05-06 10:02:14

前(fei)言(hua):

  数月前,以一个盲人摸象的姿态看了一些关于AngularJS的视频书籍,留下了我个人的一点或许是指点迷津或许是误人子弟的读后感。自以为已经达到熟悉ng的程度,但是因为刚入公司,没法直接接触代码层面的编程,日子一天天过去,ng在我脑海的残留也一天天的模糊……

  数月后,我重返ng战场,艰难的收集之前留下的记忆碎片,一番拼接下来,没有让我对ng的理解串成一条线,反而支离破碎的片段scope、template、directive、controller、config、factory、service、provide、compile、link、this.$get,让我不得不重新正视它。

  简而言之,以前的理解是针对某个点或者面,但是如果只停留在这个角度,在阅读理解项目代码时经常犯晕,一个偶然的机会,我看到了《AngularJS in action》,虽然看到的是英文版,但是看了几页之后觉得思路清晰,讲解深入浅出,我就一路看下来,并且正在继续(就我所知,目前市面上应该还没有中文版本)。下面所写内容多数来源于此书。

  下载链接:http://download.csdn.net/detail/zhengjie_1990/9416066

  有关AngularJS的介绍在前面系列文章《AngularJS入门心得1——directive和controller如何通信》篇中有提到,这里不再赘述。相较已经发展很成熟也很成功的jQuery来说,AngularJS是一门方便维护、高可扩展、可测试的前端开源框架。

AngularJS的亮点:

1.代码组织结构清晰

  AngularJS模块划分明确,不同的代码有其明确的存放处,可读性强,便于维护和扩展(后面会有代码组织结构图)。

2.功能模块易测试

  AngularJS的代码方便测试。虽然代码易测试不能成为一个框架闪光的决定性因素,但是反向思考,如果写出来的代码可测试性差将会使工作效率事倍功半。

3.双向绑定

  双向绑定的出现,无可争议的大大简化了你的代码量,与其说是技术的革新,不如说是一场思想上的颠覆与突破。回想jQuery还需要通过在DOM中找到需要的元素并在其上添加事件监听,通过触发事件(如点击等)才能解析获取DOM元素中的值。而在AngularJS中只需要将DOM中的元素与js的某个属性绑定,js属性值变化会同步到DOM元素上,同样的,DOM元素值得变化也会映射到js的属性上。夸张点说,一个是刀耕火种,一个是蒸汽驱动。

4.弥补HTML的先天不足

  HTML本身能呈现的很有限。举个例子:好比还没有解放的中国,那时只有小米加步枪,所以每一场战役都打的很艰辛,后来解放了,改革开放了,国民经济迅猛发展,靠我们自己勤劳的双手丰富了我们的武器库国防库,我们这时候有了航母、预警机、五代隐形战机等等,我们可以呈现的东西就更多更丰富了。

  这里的“小米加步枪”就是原生的HTML,局限性很大,只能打游击,很难正面交锋。但是勤劳智慧的人民就像AngularJS,我们可以创造更多种多样的指令(武器),来保卫我们的祖国,“呈现”更强大的民族。

AngularJS专业术语概览

名称

作用

Module

AngularJS中一切都是从Module模块开始的,模块是组织代码的容器,当然模块中还可以包含子模块

Config

Config是用在AngularJS application还未启动前的一些参数配置,比如路由或是一些service的配置

Routes

路由负责在应用中基于state进行页面的跳转

Views

Views是通过AngularJS编译后呈现的DOM

$scope

$scope是连接controller和view之间的桥梁,起到一种胶水的作用

Controller

定义一些属性和方法用于绑定到view的元素上,一般来说,controller是比较轻量的,它里面只放一些负责view呈现的属性和方法

Directive

指令使得AngularJS能够创建自定义的标签并实现相应的功能,可以将指令看成一种特殊的html标签

Service

Service负责提供一些通用的功能函数,比如有些数据在多个controller中都会用到,就可以定义在一个service中

AngularJS in Action读书笔记1——扫平一揽子专业术语

书中的实例

  书中提供了一个实例Angello,托管在github上面,这也是我比较欣赏的地方,很方便,git pull下来只要几步就可以轻松运行起来。书中首先是提供了Angello的一个简化版本Angello-lite。

  托管地址:https://github.com/angularjs-in-action/angello-lite

  麻雀虽小,五脏俱全。对应于上图的AngularJS结构,该项目的组织结构如下

AngularJS in Action读书笔记1——扫平一揽子专业术语

  图中:

  (1) index.html代表了view层,负责呈现;

  (2) story是一对标签,代表了指令层,其写在view的index.html中;

  (3) MainCtrl是controller层,其中定义了一些方法等;

  (4) AngelloModel是service层,其中定义了一些公用数据等;

  (5) $scope是view和controller之间的桥梁。

  下面一一介绍各个部分的作用

 1. Module

  module是AngularJS中用来组织代码的逻辑单元。本例中,创建了一个Angello的模块并赋值给变量myModule。

  代码中第一行就是创建module  

var myModule = angular.module('Angello', []);

  

  app.js

var myModule = angular.module('Angello', []);

myModule.factory('AngelloHelper', function() {
var buildIndex = function (source, property) {
var tempArray = []; for (var i = 0, len = source.length; i < len; ++i) {
tempArray[source[i][property]] = source[i];
} return tempArray;
}; return {
buildIndex: buildIndex
};
}); myModule.service('AngelloModel', function() {
var service = this,
statuses = [
{name: 'Back Log'},
{name: 'To Do'},
{name: 'In Progress'},
{name: 'Code Review'},
{name: 'QA Review'},
{name: 'Verified'},
{name: 'Done'}
],
types = [
{name: 'Feature'},
{name: 'Enhancement'},
{name: 'Bug'},
{name: 'Spike'}
],
stories = [
{
title: 'First story',
description: 'Our first story.',
criteria: 'Criteria pending.',
status: 'To Do',
type: 'Feature',
reporter: 'Lukas Ruebbelke',
assignee: 'Brian Ford'
},
{
title: 'Second story',
description: 'Do something.',
criteria: 'Criteria pending.',
status: 'Back Log',
type: 'Feature',
reporter: 'Lukas Ruebbelke',
assignee: 'Brian Ford'
},
{
title: 'Another story',
description: 'Just one more.',
criteria: 'Criteria pending.',
status: 'Code Review',
type: 'Enhancement',
reporter: 'Lukas Ruebbelke',
assignee: 'Brian Ford'
}
]; service.getStatuses = function () {
return statuses;
}; service.getTypes = function () {
return types;
}; service.getStories = function () {
return stories;
};
}); myModule.controller('MainCtrl', function(AngelloModel, AngelloHelper) {
var main = this; main.types = AngelloModel.getTypes();
main.statuses = AngelloModel.getStatuses();
main.stories = AngelloModel.getStories();
main.typesIndex = AngelloHelper.buildIndex(main.types, 'name');
main.statusesIndex = AngelloHelper.buildIndex(main.statuses, 'name'); main.setCurrentStory = function (story) {
main.currentStory = story;
main.currentStatus = main.statusesIndex[story.status];
main.currentType = main.typesIndex[story.type];
}; main.createStory = function() {
main.stories.push({
title: 'New Story',
description: 'Description pending.',
criteria: 'Criteria pending.',
status: 'Back Log',
type: 'Feature',
reporter: 'Pending',
assignee: 'Pending'
});
}; main.setCurrentStatus = function (status) {
if (typeof main.currentStory !== 'undefined') {
main.currentStory.status = status.name;
}
}; main.setCurrentType = function (type) {
if (typeof main.currentStory !== 'undefined') {
main.currentStory.type = type.name;
}
};
}); myModule.directive('story', function() {
return {
scope: true,
replace: true,
template: '<div><h4>{{story.title}}</h4><p>{{story.description}}</p></div>'
}
});

  

  (1) 其中第二个参数通过依赖注入的方式注入依赖的子模块,这样就可以在当前模块使用注入进来模块中的方法变量等。

  (2) 通过这种思想,我们可以针对不同的功能模块新建不同的Module,使得代码和项目结构更加清晰。

  (3) 从app.js中可以看出,Angello模块下定义了两个service AngelloModel和AngelloHelper,一个controller MainCtrl和一个directive story。

2.Views和Controllers

  为了方便起见,我们将AngularJS抽象成MVVM模型来讲解。

AngularJS in Action读书笔记1——扫平一揽子专业术语

  从图中可以看出将view中的元素绑定到ViewModel上,Model会有一个提醒机制,当model值发生变化时,就会触发提醒ViewModel需要更新值了。当然,来自view端值发生改变时,也会通过ViewModel上的值改变,进而刷新model上的值。这就是双向数据绑定。

  需要注意的是,要定义一个controller,需要在页面中(index.html)通过AngularJS的内置指令ng-controller进行声明。如index.html中的<h1>{{main.tite}}</h1>对应定义在controller中的title,title的任何变化都会及时的相应在index.html上。

index.html

<!DOCTYPE HTML>
<html ng-app="Angello">
<head>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
<script type="text/javascript" src="app.js"></script> <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="app.css"> <title>Angello Lite</title>
</head>
<body>
<div ng-controller="MainCtrl as main">
<div class="col-md-4">
<h2>Stories</h2>
<story class="callout"
ng-repeat="story in main.stories"
ng-click="main.setCurrentStory(story)">
</story>
<br/>
<a class="btn btn-primary" ng-click="main.createStory()">
<span class="glyphicon glyphicon-plus"></span>
</a>
</div>
<div class="col-md-6 content">
<h2>Story</h2>
<form class="form-horizontal">
<div class="form-group">
<label class="control-label" for="inputTitle">Title</label>
<div class="controls">
<input type="text" class="form-control" id="inputTitle" placeholder="Title" ng-model="main.currentStory.title" />
</div>
</div>
<div class="form-group">
<label class="control-label" for="inputStatus">Status</label>
<div class="controls">
<select id="inputStatus" class="form-control" ng-model="main.currentStatus"
ng-options="l.name for l in main.statuses"
ng-change="main.setCurrentStatus(main.currentStatus)"></select>
</div>
</div>
<div class="form-group">
<label class="control-label" for="inputType">Type</label>
<div class="controls">
<select id="inputType" class="form-control" ng-model="main.currentType"
ng-options="t.name for t in main.types"
ng-change="main.setCurrentType(main.currentType)"></select>
</div>
</div>
<div class="form-group">
<label class="control-label" for="inputDescription">Description</label>
<div class="controls">
<textarea id="inputDescription" class="form-control" placeholder="Description" rows="3"
ng-model="main.currentStory.description"></textarea>
</div>
</div>
<div class="form-group">
<label class="control-label" for="inputAcceptance">Acceptance Criteria</label>
<div class="controls">
<textarea id="inputAcceptance" class="form-control" placeholder="Acceptance Criteria" rows="3"
ng-model="main.currentStory.criteria"></textarea>
</div>
</div>
<div class="form-group">
<label class="control-label" for="inputReporter">Reporter</label>
<div class="controls">
<input type="text" class="form-control" id="inputReporter" placeholder="Reporter" ng-model="main.currentStory.reporter" />
</div>
</div>
<div class="form-group">
<label for="inputAssignee">Assignee</label>
<div class="controls">
<input type="text" class="form-control" id="inputAssignee" placeholder="Assignee" ng-model="main.currentStory.assignee" />
</div>
</div>
</form>
</div>
</div>
</body>
</html>

  

3.Service

  前面提到过,Service是一些公用的数据和方法的封装,可以用在不同的controller中。AngularJS可以使用依赖注入的方法将这些定义的service注入到相应的controller中,便可以使用service中的数据和方法。

4.Directive

  directive是angularjs的一大亮点。AngularJS自己有一些内置指令如ng-click、ng-if等,用户也可以自己定义指令,如这里的story。

  此篇旨在大致的了解了AngularJS的过人之处,如何构建项目,每个部分的作用。

  如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!如果您想持续关注我的文章,请扫描二维码,关注JackieZheng的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。

  AngularJS in Action读书笔记1——扫平一揽子专业术语

友情赞助

如果你觉得博主的文章对你那么一点小帮助,恰巧你又有想打赏博主的小冲动,那么事不宜迟,赶紧扫一扫,小额地赞助下,攒个奶粉钱,也是让博主有动力继续努力,写出更好的文章^^。

    1. 支付宝                          2. 微信

AngularJS in Action读书笔记1——扫平一揽子专业术语                      AngularJS in Action读书笔记1——扫平一揽子专业术语