AngularJS 30分钟入门【转-译】by WuBin 武斌

关于AngularJS的学习和总结。 本文转自“cnblog-AngularJS 30分钟入门【转-译】

引用自:http://www.revillweb.com/tutorials/angularjs-in-30-minutes-angularjs-tutorial/,翻译如下:

简介

我三年前开始使用 AngularJS,那时它还是一个新鲜事物。 现在 AngularJS已经成为了一个最受欢迎的 JavaScript 框架之一,多亏了AngularJS 团队作出的努力。

这个教程使用的是1.3.4版本,涵盖非常基础东西,但是都是在使用过程中总结出来的最佳实践经验。

Setup

开始前,你先创建一个文件夹,命名为 angularjs-tutorial ,然后在文件夹中建立下面几个文件,文件目录结构如下:

- angularjs-tutorial
	| - main.ctrl.js
	| - app.js
	| - index.html

打开 index.html 文件,输入一下简单的 HTML内容,文件头部引用来自其它站点CDN的 AngularJS文件 and Twitter Bootstrap样式文件。我们准备使用 Twitter Bootstrap 作为 CSS 框架,这样会让我们更容易更快地创建视图布局,可以让我们将注意力放在 AngularJS上面。如果你想了解更多 Twitter Bootstrap 有关的知识,请登陆官网查看相关教程 Twitter Bootstrap Tutorial。

<!DOCTYPE html>
<html>
<head lang="en">
	<meta charset="UTF-8">
	<title>AngularJS Tutorial</title>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.min.js"></script>
	<script src="app.js"></script>
	<script src="main.ctrl.js"></script>
</head>
<body>
</body>
</html>

这些 HTML 代码也引用了我们自己创建的 app.js 和main.ctrl.js 文件。

让你的网页Angular化

在我们的 app.js 我们要先搞一个 AngularJS module 出来用在我们的app里面。复制下面的代码到 app.js

angular.module('app', []);

这个 angular.module() 函数用作angular module的 setter 和getter 。第一个参数是 module 的名称,我们起名为 app, 第二个参数我们提供了一个数组。如果给出了一个数组,那么angular会创建并取得相应的app module,稍后我们创建自己的controller你就可以看到。

提示:在更复杂的应用中,我们会用module数组来代替上面所说的空数组。

现在我们需要告诉angular,我们想将这个module用在什么地方,打开 index.html ,将 ng-app=’app’ 添加到 <body> 标签,如下所示:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>AngularJS Tutorial</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.min.js"></script>
</head>
<body ng-app="app">

</body>
</html>

这里告诉了angular ,所有在body里面的东西都是我们 AngularJS application 的一部分,我们这里的AngularJS application 命名为 app.

控制器 controller#

AngularJS 提供一种宽松的 MVC 结构,更准确来说是 MVVM 模式。控制器是你处理业务逻辑的地方,本质上来说,控制器是用来控制数据并且将数据提供给视图用于显示的东西。 为了声明我们的 controller,打开 main.ctrl.js 文件,将下面的代码添加进去。

angular.module('app').controller("MainController", function(){
    var vm = this;
});

在声明的代码中,我们首先获取了一个 我们之前声明的app module,然后用 controller 函数初始化一个新的controller。这个 controller 函数有两个参数,第一个参数是控制器名称,第二个参数是一个函数,这个函数是用来放我们的控制代码的,我们要实现的功能就是写在这个函数里面。

在我们使用这个控制器前,我们需要告诉 angular那部分HTML 代码是属于这个控制器管理的。在一个html文档中,你可以有很多个控制器,并且可能有多个控制器管理同一段html代码,控制器之间甚至可以嵌套。在我们非常简单的例子中,我们准备只用一个控制器来管理这个页面好了。我们可以用 controllerAs 语法来声明(等一下再细说),打开 index.html ,将下面代码放在 body 标签。

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>AngularJS Tutorial</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.min.js"></script>
</head>
<body ng-app="app" ng-controller="MainController as main">

</body>
</html> # 理解 scope 通常来说你可以将 `$scope` 注入到controller,然后将全部controller变量分配到这个scope对象,这样这些变量就可以在html使用了。 然后,更好的途径,被AngularJS团队推荐的做法是使用 controllerAs  。这种方式提供了更 semantic 的途径在html中去声明 controllers ,并且防止当 multiple-nested controllers 出现的时候诸如 scope bleed 的问题。

我们将一个 controller 实例分配到变量 vm 中,这个变量代表了 ViewModel ,在 John Papa的文章 style guide 中 推荐这样做。我们将分配所有需要在view中可访问的控制器变量到这个对象,这样angular 就可以起到诸如双休绑定等魔法般的作用了。

为了理解scope,我们声明一个简单的变量 title ,用来保存在我们页面上要显示的标题。打开 main.ctrl.js 添加下面的代码。

angular.module('app').controller("MainController", function(){
    var vm = this;
    vm.title = 'AngularJS Tutorial Example';
}); 为了在我们的页面显示这个标题文本,我们使用下面的语法。

<!DOCTYPE html>

AngularJS Tutorial

在上面的例子中,我们使用了两对花括号将title显示在h1标签中,两对花括号可以让 angular 知道这是个变量。 之前我们用MainController as main来声明了一个控制器的别名,我们通过用控制器的别名main加变量来访问控制器 scope 里面的变量title,如。现在想一下,如果我们一个文档中有几个不同的 controller,你如果不用别名加变量的形式,而是直接写,那么你将很难区分那个变量是属于哪个控制器的。另外,如果不同的控制器里面有相同名称的变量,那么问题就更严重了 (例如: scope bleed).

如果你在一个网页打开 index.html ,你可以看到一个无聊title 的文本显示在网页上面。

理解绑定

双向绑定是 AngularJS 的主要卖点之一。让我们看一下什么情况。在main.ctrl.js 中增加一个变量 searchInput 如下:

angular.module('app').controller("MainController", function(){
    var vm = this;
    vm.title = 'AngularJS Tutorial Example';
    vm.searchInput = '';
}); 打开 index.html ,添加一个简单的输入框:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>AngularJS Tutorial</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.min.js"></script>
    <script src="app.js"></script>
    <script src="main.ctrl.js"></script>
</head>
<body ng-app="app" ng-controller="MainController as main">
<div class="container">
    <h1></h1>
    <div class="input-group">
        <span class="input-group-addon">
            <span class="glyphicon glyphicon-search"></span>
        </span>
        <input type="text" class="form-control" ng-model="main.searchInput">
    </div>
    <p></p>
</div>
</body>
</html> 除此以外添加双重花括号包住 searchInput 变量,这样输入框的值就显示在双重花括号的位置。在输入框中我们添加一个 `ng-model` 属性,并制定值为 searchInput ,这个值就是来自main controller的searchInput变量。 现在输入框绑定了同名的变量,它可以受控制器管理。 如果你在浏览器打开index.html 页面,在输入框中输入内容,你可以立刻看到的位置显示出文本框的内容。

使用 ngRepeat

AngularJS 提供很多内建的指令方便你完成常见的功能。ngRepeat 指令可让你枚举一个集合,然后显示在页面上。我们建一个数组来试一下。把 main.ctrl.js 改为下面这样。

angular.module('app').controller("MainController", function(){
    var vm = this;
    vm.title = 'AngularJS Tutorial Example';
    vm.searchInput = '';
    vm.shows = [
        {
            title: 'Game of Thrones',
            year: 2011,
            favorite: true
        },
        {
            title: 'Walking Dead',
            year: 2010,
            favorite: false
        },
        {
            title: 'Firefly',
            year: 2002,
            favorite: true
        },
        {
            title: 'Banshee',
            year: 2013,
            favorite: true
        },
        {
            title: 'Greys Anatomy',
            year: 2005,
            favorite: false
        }
    ];
}); 提示:在真实的开发场景,数据可能通过服务或者本地文件的API加载进来的。 现在我们有了一个数组,可以使用ngRepeat来遍历展示每一项数据。打开 index.html 添加如下代码:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>AngularJS Tutorial</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.min.js"></script>
    <script src="app.js"></script>
    <script src="main.ctrl.js"></script>
</head>
<body ng-app="app" ng-controller="MainController as main">
<div class="container">
    <h1></h1>
    <div class="input-group">
        <span class="input-group-addon">
            <span class="glyphicon glyphicon-search"></span>
        </span>
        <input type="text" class="form-control" ng-model="main.searchInput">
    </div>
    <h3>A list of TV shows</h3>
    <ul class="list-group">
        <li class="list-group-item" ng-repeat="show in main.shows"> <span class="badge"></span></li>
    </ul>
</div>
</body>
</html> 在这个例子ngRepeat会复制列表的项,然后绑定数组的数据展示到页面。我们可以用  读取每一项的属性,然后去展示在<li>元素中。

隐藏和显示元素

其它AngularJS 指令可以让你用判断和表达式来显示和隐藏html元素、这些指令是 ngHide, ngShow, ngSwitch & ngIf。甚至通过这些指令日光一个相似的结果,这对于某些情况很有用。ngSwitch 指令很有用,当你碰到条件判断是,例如单选框切换。 ngHide, ngShow 和 ngIf 很相似。ngIf 会移除受影响的元素, ngHide 和 ngShow 只是增加一个 display: none;样式值来隐藏元素。

Therefore ngIf should be used where possible as this will save the browsers memory due to a decluttered DOM. ngHide and ngShow are particularly useful when the items are animated as the additional overhead of adding the element back to the DOM with ngIf can often affect the animations.

For our simple example we would like to add a star next to each TV show in the list only if the show is marked as a favorite. Update index.html to use ngIf as follows.

<h3>A list of TV shows</h3>
<ul class="list-group">
    <li class="list-group-item" ng-repeat="show in main.shows"><span class="glyphicon glyphicon-star" ng-if="show.favorite"></span>  <span class="badge"></span></li>
</ul> This simply added the star icon to the DOM when the show.favorite property is equal to true. It’s worth mentioning that expressions can be used here so something like show.favorite == true orshow.favorite != false would also work.

在ngRepeat中使用过滤器

AngularJS provides the ability to easily filter repeated content. Let’s use the search input we created earlier to allow users to filter the TV show list.

<h3>A list of TV shows</h3>
<ul class="list-group">
    <li class="list-group-item" ng-repeat="show in main.shows | filter:main.searchInput"><span class="glyphicon glyphicon-star" ng-if="show.favorite"></span>  <span class="badge"></span></li>
</ul> It’s that easy! Imagine trying to do something like that with jQuery. Have a play around with this implementation below.

Let’s make things a little more complicated and add the option to change the order of the list items. Updatemain.ctrl.js with another set of objects specifying the order types available.

vm.orders = [
    {
        id: 1,
        title: 'Year Ascending',
        key: 'year',
        reverse: false
    },
    {
        id: 2,
        title: 'Year Descending',
        key: 'year',
        reverse: true
    },
    {
        id: 3,
        title: 'Title Ascending',
        key: 'title',
        reverse: false
    },
    {
        id: 4,
        title: 'Title Ascending',
        key: 'title',
        reverse: true
    }
];
vm.order = vm.orders[0]; Now add a select menu to index.html so the user is able to choose the list order and add an additional filter to the ngRepeat we added earlier.

<body ng-app="app" ng-controller="MainController as main">
<div class="container">
    <h1></h1>
    <div class="input-group">
        <span class="input-group-addon">
            <span class="glyphicon glyphicon-search"></span>
        </span>
        <input type="text" class="form-control" ng-model="main.searchInput">
    </div>
    <h3>A list of TV shows</h3>
    <ul class="list-group">
        <li class="list-group-item" ng-repeat="show in main.shows | filter:main.searchInput | orderBy:main.order.key:main.order.reverse"><span class="glyphicon glyphicon-star" ng-if="show.favorite"></span>  <span class="badge"></span></li>
    </ul>
    <select class="form-control pull-right" ng-model="main.order" ng-options="order as order.title for order in main.orders"></select>
</div>
</body> Above we have added an orderBy filter to the ngRepeat specifying which key of the show object we want to order by, in this case title. We then specified the direction of the order which is stored within the orders objects as reverse. To populate the select menu we use the ngOptions directive which you can read more about here.

See it in action below by changing the selected value in the select menu.

表单检验

Collecting data from a user makes up a large part of web applications. AngularJS makes it easy to validate form data before it is used by your application. In this simple example we will create a form allowing the user to add a new TV show to the list. Open index.html and add the following HTML to create a simple form.

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>AngularJS Tutorial</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.min.js"></script>
    <script src="app.js"></script>
    <script src="main.ctrl.js"></script>
</head>
<body ng-app="app" ng-controller="MainController as main">
<div class="container">
    <h1></h1>
    <div class="input-group">
        <span class="input-group-addon">
            <span class="glyphicon glyphicon-search"></span>
        </span>
        <input type="text" class="form-control" ng-model="main.searchInput">
    </div>
    <h3>A list of TV shows</h3>
    <ul class="list-group">
        <li class="list-group-item" ng-repeat="show in main.shows | filter:main.searchInput | orderBy:main.order.key:main.order.reverse"><span class="glyphicon glyphicon-star" ng-if="show.favorite"></span>  <span class="badge"></span></li>
    </ul>
    <select class="form-control pull-right" ng-model="main.order" ng-options="order as order.title for order in main.orders"></select>
    <div class="clearfix"></div>
    <h3>Add a new TV Show</h3>
    <form name="main.addForm" class="form">
        <div class="form-group">
            <label>Title</label>
            <input type="text" class="form-control" ng-model="main.new.title" required />
        </div>
        <div class="form-group">
            <label>Year</label>
            <input type="number" min="1900" max="2030" class="form-control" ng-model="main.new.year" required />
        </div>
        <div class="row">
            <div class="col-xs-6">
                <label>Favorite: <input type="checkbox" ng-model="main.new.favorite" /></label>
            </div>
            <div class="col-xs-6">
                <button class="btn btn-success pull-right"><span class="glyphicon glyphicon-plus-sign"></span> Add</button>
            </div>
        </div>
    </form>
</div>
</body>
</html> This simple form will allow the user to enter a show title, year and specify if it is a favorite. On the title and year fields we have added a required attributed marking this field as required. Additionally we have specified the field type for the year input as number and added the additional min and max properties. AngularJS provides out of the box form validation and will automatically provide feedback to the user when they click the add button. If the user has not entered a value in either of the required fields they will be prompted with an error message. Also, if the user has not entered a number between 1900 and 2030 they will be instructed to do so. Try it yourself using the pen below.

Read more about forms with AngularJS here.

Responding to simple events

The final part of this AngularJS tutorial will show you how events are used within the framework. Events have always been an important part in JavaScript frameworks and libraries and it is no different here, even with Angular’s two-way data binding.

The form we just created is useless if the user is unable to actually submit the data and add it to the list of shows. Add the following code to the bottom of MainController.

vm.new = {};
vm.addShow = function() {
    vm.shows.push(vm.new);
    vm.new = {};
}; The above code declares an object called new which the form uses to store its input values denoted by the ngModel value (i.e. ng-model="main.new.year"). Also a function addShow is created which pushes the new object into the shows array and adds it to the list within the view.

AngularJS provides various event directives such as ngClick, ngChange, ngFocus, etc. that we can use to react upon. In our simple example we will use the ngSubmit directive to trigger the addShow function when the form is successfully submitted. Open index.html and amened your form declaration to include this directive as shown below.

<form name="main.addForm" class="form" ng-submit="main.addShow()"> Now, when the form passes validation and the user clicks the add button this addShow function will get called, adding the new show to the list. Have a go!

This is an extremely simple example of one in many event directives AngularJS provides, head over to the documentation to learn more.

结论

在这个快速入门教程里, 你现在应该掌握了几个AngularJS 概念,你可以用这些知识搭建一下简单的网页应用了。 AngularJS offers so much more than I can show you in 30 minutes, if you liked this tutorial then please subscribe below to receive updates regarding up coming advanced AngularJS 教程.

Published 04 November 2015