AngularJS 30分钟入门
引用自:http://www.revillweb.com/tutorials/angularjs-in-30-minutes-angularjs-tutorial/,以下以作者的口吻翻译。
简介
我三年前开始使用 AngularJS,那时它还是一个新鲜的的未知的东西时候。 现在 AngularJS已经成为了一个最受欢迎的 JavaScript 框架之一,多亏了AngularJS 团队做出的努力。
这个教程使用的是1.3.4版本,将会涵盖非常基础东西,但是都是Google和我的使用经验中总结出来的最佳实践.
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
, 第二个参数我们提供了一个数组。(先休息,稍后继续) If an array is provided then angular will create the app module as opposed to retrieving it which you’ll see later when we create our controller.
In more complex applications you will provide an array of module dependencies as opposed to an empty array as with this example.
Now we need to tell angular where we want to use this module, open up index.html
and add ng-app=‘app‘
to the <body>
tag as shown below.
<!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>
This tells angular that everything within the DOM under body is part of our AngularJS application called app
.
The controller
AngularJS provides a loose MVC structure more accurately described as MVVM. The controller is where your business logic should be handled, essentially the controller ‘controls’ the data and provides it to the view for display. To declare our main controller open up main.ctrl.js
and add the following JavaScript code.
angular.module(‘app‘).controller("MainController", function(){
var vm = this;
});
In the code above we first retrieve the app module we created early and then use the controller
function to instantiate a new controller. The controller
function takes two parameters. The first is the controller name and the second is a function where we will place our controlling code.
Before we can use the controller we need to tell angular which part of our HTML document this controller has governance over. You can have many controllers per document and many controllers governing the same section of a document, you can even have nested controllers. In our very simple example we are going to have a single controller governing the entire page. We will use the controllerAs
syntax to declare this (more on this later), open index.html
and add the following to the body tag.
<!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>
Understanding scope
Traditionally you would inject $scope
into the controller and assign all controller variables to the scope object which will then make them accessible within the view. However, the better approach and recommended by the AngularJS team is the controllerAs syntax. This provides a more semantic approach to declaring controllers within your HTML and also prevents issues such as scope bleed when multiple-nested controllers are present.
We capture the controller instance into the vm
variable which stands for ViewModel as recommended by John Papa’s style guide. We will then assign all controller variables that we need access to within the view to this object so angular can work its magic, such as two-way data binding.
To understand the scope lets declare a simple variable called title
which will hold some title text we want to display within our web page. Open main.ctrl.js
and add the following.
angular.module(‘app‘).controller("MainController", function(){
var vm = this;
vm.title = ‘AngularJS Tutorial Example‘;
});
To display this text within our web page we use the following syntax.
<!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">
<div class="container">
<h1>{{main.title}}</h1>
</div>
</body>
</html>
In the above example we are displaying the title text inside a h1
tag using a set of curly braces so that angular knows that this is a variable. We access the controllers scope by prefixing the variable with main matching ourControllerAs
definition. Now imagine that we had multiple controllers in the same document and you were referencing multiple variables using the traditional method where you would simple do {{title}}
. It would be very difficult to see which scope the variables were present in. Additionally it would also be easy to accidentally have multiple variables with the same name (i.e scope bleed).
If you open index.html
within a web page you should see the title text output as a header on a very boring web page.
Understanding binding
Two-way data binding is one of the main selling points of AngularJS so lets take a look what its all about. Withinmain.ctrl.js
add another variable called searchInput
as shown below.
angular.module(‘app‘).controller("MainController", function(){
var vm = this;
vm.title = ‘AngularJS Tutorial Example‘;
vm.searchInput = ‘‘;
});
Open index.html
and add a very simple search input using the following code.
<!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>{{main.title}}</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>{{main.searchInput}}</p>
</div>
</body>
</html>
In addition to adding a search input we have used the curly braces again to output the searchInput
variable. On the text input we have added the ng-model
directive and specified the searchInput
variable from our main controller. This input is now bound to this variable making the inputs value available from within the controller code and also from anywhere within the HTML document that is governed by the controller. Now if you openindex.html
in a browser and type within the search box you should instantly see the search input value printed underneath as you type. Have a go using the live preview below.
Using ngRepeat
AngularJS provides a wide range of built in directives for you to help you perform common tasks. The ngRepeat directive allows you to iterative through items and display them on the page. Let’s create an array of objects we can iterate through. Update main.ctrl.js
to have the following array.
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
}
];
});
In a real-world scenario data such as this would probably be loaded via an API using a service to interact and store the data locally.
Now we have an array we can use the ngRepeat directive to loop through each TV show and create an unordered list within our web page. Open index.html
and add the following code.
<!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>{{main.title}}</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">{{show.title}} <span class="badge">{{show.year}}</span></li>
</ul>
</div>
</body>
</html>
In this example ngRepeat will copy the list item element for each item in our shows array. We can then access properties of each show using {{show.[property]}}
to display them within the list element.
Hiding and showing elements
Another set of directives that AngularJS provides allow you to easily hide and show DOM elements based on criteria or an expression. These directives are ngHide, ngShow, ngSwitch & ngIf. Even though these directives provide a similar result they are useful in different situations. The ngSwitch directive is useful when you have a case like situation, such as a radio button toggle. ngHide, ngShow and ngIf are very similar except with a fundamental difference. ngIf will remove the affected element from the DOM where ngHide and ngShow will essentially add a display: none;
to it hiding it from view.
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> {{show.title}} <span class="badge">{{show.year}}</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.
Using filters with 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> {{show.title}} <span class="badge">{{show.year}}</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>{{main.title}}</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> {{show.title}} <span class="badge">{{show.year}}</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.
Form validation
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>{{main.title}}</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> {{show.title}} <span class="badge">{{show.year}}</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 thedocumentation to learn more.
Conclusion
In this quick tutorial you should now have a good working understand of many AngularJS concepts which will allow you to build simple single page applications. 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 tutorials.
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。