AngularJS诞生于2009年,由Misko Hevery
等人创建,后为Google所收购。是一款优秀的前端JS框架,已经被用于Google的多款产品当中。

一、angularJS简介

AngularJS有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等等。

1.什么是 AngularJS?

        AngularJS 是一个 JavaScript 框架。它是一个以 JavaScript
编写的库。AngularJS是协助搭建单页面工程的开源前端框架。它通过MVC模式使得开发与测试变得更容易。AngularJS
是以一个 JavaScript 文件形式发布的,可通过 script 标签添加到网页中:

<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>

AngularJS
使得开发现代的单一页面应用程序(SPAs:Single Page
Applications)变得更加容易。

  • AngularJS 把应用程序数据绑定到 HTML
    元素。

  • AngularJS 可以克隆和重复 HTML
    元素。

  • AngularJS 可以隐藏和显示 HTML
    元素。

  • AngularJS 可以在 HTML
    元素”背后”添加代码。

  • AngularJS 支持输入验证。

 

                                                                       
                                          ———–百度百科

2.AngularJs的核心思想

  • 将视图与业务逻辑解耦。在AngularJS中通过数据视图双向绑定实现。这将提高代码的可测试性。

    图片 1

  • 遵循MVC模式开发,鼓励视图、数据、逻辑组件间松耦合。

    图片 2

  • 将测试与应用程序编写同等重要。在编写模块同时编写测试。因为各组件的松耦合,使得这种测试得以实现。

应用程序页面端与服务器端解耦。两方只需定义好通信API,即可并行开发

 

 

3.四大核心特性

MVC、模块化、双向数据绑定、指令系统

1)MVC

下面做入门介绍,本篇主要以代码的形式解析。

(1)MVC基本介绍

MVC只是手段,终极目标是模块化和复用。angularJS的MVC都是借助于$scope实现的!!!

图片 3

起源:1979年,Trygve Reenskaug第一次正式提出了MVC模式。

*model:数据模型层

*controller:视图层,负责展示

*view:业务逻辑和控制逻辑

好处:职责清晰,代码模块化

<!DOCTYPE html>
<html ng-app>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="js/angular.min.js"></script>
    <script src="js/helloAngular.js"></script>
</head>
<body>
    <div ng-controller="HelloAngular">
        <p>{{greeting.text}},Angular</p>
    </div>
</body>
</html>

helloAngular.js

function HelloAngular($scope){
    $scope.greeting = {
        text:"Hello"
    };
}

图片 4

分析以上代码:

ng-controller
为控制器,它赋值成HelloAngular。

<p>{{greeting.text}},Angular</p>
为视图,是页面看得到的东西。

js中有一段 text:”Hello”,在界面上又有
greeting.text来取值,这就是model。

上述js代码定义了全局变量,会污染全局空间,一般不建议采用,angular模块化可以解决该问题

1.在web页面引入angularJS的js文件。

(2)前端MVC的困难

图片 5

2)模块化

<!DOCTYPE html>
<html ng-app="HelloAngular">
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="js/angular.min.js"></script>
    <script src="js/helloAngular.js"></script>
</head>
<body>
    <div ng-controller="helloAngular">
        <p>{{greeting.text}},Angular</p>
    </div>
</body>
</html>

helloAngular.js

var myModule = angular.module("HelloAngular",[]);
myModule.controller("helloAngular",["$scope",
    function HelloAngular($scope){
        $scope.greeting = {
            text:"Hello"
        };
    }
]);

先申明一个模块,在模块的基础上定义一个控制器。

第一个$scope的使用体现了angularJS依赖注入的特性。

图片 6

3)双向数据绑定

图片 7

目前大多数前端框架都是单向数据绑定:jQueryUI、BackBone、Flex

单向数据绑定处理流程:首先把模板写好,然后加上数据,数据可能是从后台服务器读取出来的,把模板和数据结合在一起,通过我们的数据绑定机制生成一段html标签,再把这一段HTML标签插入到文档流里面。

缺点:HTML标签生成完之后就没法再改变了。

图片 8

双向数据绑定核心想法:视图和数据是对应的,当视图上面的内容发生变化的时候,它希望数据模型里面也立刻发生变化,当数据模型发生变化的时候,视图它自己会自动去更新,这里需要借助一个事件机制。

eg:

<!DOCTYPE html>
<html ng-app>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="js/angular.min.js"></script>
</head>
<body>
    <input ng-model="greeting.text">
    <p>{{greeting.text}},Angular</p>
</body>
</html>

图片 9

 这里前面的文字会随着输入而改变。

 

4)指令系统

用一个例子来理解:

<!DOCTYPE html>
<html ng-app="myModule">
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="js/angular.min.js"></script>
    <script src="js/hiEveryone.js"></script>
</head>
<body>
    <hello></hello>
</body>
</html>

hiEveryone.js

var myModule = angular.module("myModule",[]);
myModule.directive("hello",function (){
        return{
            restrict:"E",
            template:"<div>hi,everyone!</div>",
            replace:"true"
        }
    }
);

图片 10

hello为directive的名称。directive后面详细讲解。

可以通过官网下载,也可以在百度上搜索,建议从官网上下载。

4.来看看使用AngularJs怎么做

图片 11

几乎没有DOM操作,更专注于业务逻辑!

http://www.angularjs.net.cn/这个中文网地址。上面也有相关教程。

二、angularJS指令

AngularJS 通过被称为 指令 的新属性来扩展 HTML。

AngularJS 通过内置的指令来为应用添加功能。

AngularJS 允许你自定义指令。

AngularJS 指令是扩展的 HTML 属性,带有前缀 ng-。

1.最基本的指令:

   1) ng-app指令

       ng-app指令标记了AngularJS脚本的作用域,在<html>中添加ng-app属性即说明整个<html>都是AngularJS脚本作用域。开发者也可以在局部使用ng-app指令,如<div ng-app>,则AngularJS脚本仅在该<div>中运行。

angularJS从ng-app开始启动的,在任意的一个单页angularJS应用里面,ng-app只能有一个。

   2) ng-controller指令

        ng-controller 指令定义了应用程序控制器。控制器是 JavaScript
对象
,由标准的 JavaScript 对象的构造函数 创建。

   3) ng-model指令

ng-model指令把元素值(比如输入域的值)绑定到应用程序。

   4) ng-bind 指令

       ng-bind 指令把应用程序数据绑定到
HTML 视图。

   5) ng-init 指令

       ng-init
指令初始化应用程序数据,中间用分号来分隔。通常情况下,不使用
ng-init。将使用一个控制器或模块来代替它。

2.eg:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body>
    <div ng-app="" ng-init="name='Joe';age='24'">
        姓名:<input type="text" ng-model="name"><br>
        年龄:<input type="text" ng-model="age"><br>
        <p>您输入的是:</p>
        <p>{{name}}</p>
        <p ng-bind="age"></p>
    </div>
</body>
</html>

图片 12
——>图片 13 
   

在页面一直刷新或网络不好的时候,第一行结果显示区域可能会出现{{name}},这样给用户的体验不好,如果使用ng-bind就不会出现这个问题,它在狂刷新的时候出现的是空白。

一般情况下,会首页index.html加载angularJS核心库,在首页使用ng-bind比较好,后续的通过模板或者其他加载进来的页面用双花括号绑定就可以了,这样的话可以保证用户看不到那种很丑的表达式。

上诉代码实际上实现了双向绑定,输入框的内容改变的时候,下面的文字也会相应改变。

注意:在没有使用控制器的时候不要这样写:

<div ng-app="myApp" ng-controller="myCtrl" ng-init="name='Joe',age='24'">

这样会报错,因为myApp和myCtrl还没有定义,不能直接引用。直接按照上面的例子那样写就行。

2.代码分析

三、angularJS表达式

AngularJS
表达式写在双大括号内:{{ expression }}

AngularJS 表达式把数据绑定到 HTML,这与 ng-bind 指令有异曲同工之妙。

AngularJS 将在表达式书写的位置”输出”数据。

AngularJS 表达式 很像
JavaScript 表达式:它们可以包含文字、运算符和变量。

1.数字

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body>
    <div ng-app="" ng-init="num1=1;num2=6">
        <p>和为:</p>
        <p>{{num1+num2}}</p>
    </div>
</body>
</html>

                 
——>图片 14

2.字符串

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body>
    <div ng-app="" ng-init="str1='Hello';str2='World!'">
        <p>结果为:</p>
        <p>{{str1+" "+str2}}</p>
    </div>
</body>
</html>

——–>图片 15

3.数组

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body>
<div ng-app="" ng-init="arr=[1,2,3,5,6,9]">
    <p>结果为:</p>
    <p>{{arr[0]}}</p>
</div>
</body>
</html>

——–>图片 16

4.对象

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body>
<div ng-app="" ng-init="obj={firstName:'John',lastName:'Doe'}">
    <p>结果为:</p>
    <p>{{obj.lastName}}</p>
</div>
</body>
</html>

——–>图片 17

 

下面是copy来的例子:

四、angularJS控制器

<!DOCTYPE html>
<html lang="en" ng-app="todoApp">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="angular.min.js"></script>

    <script>
angular.module('todoApp', []) //定义模块
    .controller('TodoListController', function() { //定义控制器
        var todoList = this;
        todoList.todos = [ //定义一些初始化的属性
            { text: 'learn AngularJS', done: true },
            { text: 'build an AngularJS app', done: false }
        ];

        todoList.addTodo = function() { //定义方法
            todoList.todos.push({ text: todoList.todoText, done: false });
            todoList.todoText = '';
        };

        todoList.remaining = function() { //定义方法
            var count = 0;
            angular.forEach(todoList.todos, function(todo) { //遍历todos
                count += todo.done ? 0 : 1;
            });
            return count;
        };

        todoList.archive = function() { //定义方法
            var oldTodos = todoList.todos;
            todoList.todos = [];
            angular.forEach(oldTodos, function(todo) {
                if (!todo.done) todoList.todos.push(todo);
            });
        };
    });
</script>
</head>

<body>
    <div ng-controller="TodoListController as todoList">

        {{todoList.remaining()}} of {{todoList.todos.length}} remaining [
        <a href="" ng-click="todoList.archive"></a>
        ]

        <ul>
            <li ng-repeat="todo in todoList.todos">
                <lable>
                    <input type="checkbox" ng-model="todo.done">
                    {{todo.text}}
                </lable>
            </li>
        </ul>

        <form ng-submit="todoList.addTodo()">
            <input type="text" ng-model="todoList.todoText" size="30" placeholder="请输入新的项目">
            <input type="submit" value="add">
        </form>


    </div>

    <div ng-app="myApp" ng-controller="myCtrl">
        名字: <input ng-model="name">
    </div>

    <script>
        var app = angular.module('myApp', []);
        app.controller('myCtrl', function($scope) {
            $scope.name = "John Doe";
        });
    </script>
</body>

</html>

1.MVC-Controller实现方式一

图片 18

控制器负责和视图进行双向交互,也负责跟数据模型进行双向交互。

问题:如果视图1和视图2没有什么逻辑关系,“控制器”的角色就很尴尬。

在一些比较小型的、玩具型的小东西里面可以用这种方式去实现。

  

2.MVC-Controller实现方式二

图片 19

问题:如果控制器1和控制器2里面有两个方法一模一样怎么办?

错误解决方法:

图片 20

请注意,这是一个坑,在ng中不要这样做。最好是将公共的部分抽成一个Service。

其中ng-app是指定一个angularJS应用。

3.MVC-Controller实现方式三

图片 21

对应js代码为:angular.module(“todoApp”,[]);定义一个module模块

4.Controller使用过程中的注意点

1)不要试图去复用controller,一个控制器一般只负责一小块试图。

2)不要在controller中操作DOM,这不是控制器的职责

3)不要在controller里面做数据格式化,ng有很好用的表单控件。

4)不要在controller里面做数据过滤操作,ng有$filter服务

5)一般来说,controller是不会互相调用的,控制器之间的交互会通过事件进行。

 

ng-controller指定一个控制器,指明该标签下所有的子元素都归该控制器管理。

五、angularJS作用域($scope)

对应js代码为:     .controller(‘TodoListController’, function()
{});定义一个控制器

1.概念

Scope(作用域) 是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带。

Scope 是一个对象,有可用的方法和属性。

Scope 可应用在视图和控制器上。

是一个树型结构(是一个POJO),与DOM标签平行。可以继承父作用域上面的属性和方法。是整个angularJS的基础。

可以使用angular.element($0).scope()进行调试。

!根作用域

      所有的应用都有一个 $rootScope,它可以作用在 ng-app
指令包含的所有 HTML 元素中。

     $rootScope 可作用于整个应用中。是各个 controller 中 scope
的桥梁。用 rootscope 定义的值,可以在各个 controller 中使用。

!!作用域是有一个层次结构的,它在最内层的作用域上面如果获得不到一个属性,它就会一次向上去找,(类似js里面的原型查找)直到找到根作用域。

<!DOCTYPE html>
<html ng-app>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="js/angular.min.js"></script>
    <script src="js/MVC1.js"></script>
</head>
<body>
    <div ng-controller="CommonController">
        <div ng-controller="Controller1">
            <p>{{greeting.text}},Angular</p>
            <button ng-click="test1()">test1</button>
        </div>
        <div ng-controller="Controller2">
            <p>{{greeting.text}},Angular</p>
            <button ng-click="test2()">test2</button>
            <button ng-click="commonFn()">通用</button>
        </div>
    </div>
</body>
</html>

MVC1.js

function CommonController($scope){
    $scope.commonFn=function(){
        alert("这里是通用功能!");
    };
}

function Controller1($scope) {
    $scope.greeting = {
        text: 'Hello1'
    };
    $scope.test1=function(){
        alert("test1");
    };
}

function Controller2($scope) {
    $scope.greeting = {
        text: 'Hello2'
    };
    $scope.test2=function(){
        alert("test2");
    }
}

图片 22

一个ng-app可以定义多个控制器。

2.事件机制

HTML标签都是树形结构,有根有叶子,我们可以向上往根的方向传播,也可以向下往叶子的方向传播。

传播事件的方式:

      1)向上传播($emit())

      2)向下传播($broadcast())

<!DOCTYPE html>
<html ng-app>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="js/angular.min.js"></script>
    <script src="js/scope.js"></script>
</head>
<body>
    <div ng-controller="EventController">
        Root scope
        MyEvent count: {{count}}
        <ul>
            <li ng-repeat="i in [1]" ng-controller="EventController">
                <button ng-click="$emit('MyEvent')">
                    $emit('MyEvent')
                </button>
                <button ng-click="$broadcast('MyEvent')">
                    $broadcast('MyEvent')
                </button>
                <br>
                Middle scope
                <tt>MyEvent</tt> count: {{count}}
                <ul>
                    <li ng-repeat="item in [1, 2]" ng-controller="EventController">
                        Leaf scope
                        <tt>MyEvent</tt> count: {{count}}
                    </li>
                </ul>
            </li>
        </ul>
    </div>

</body>
</html>

scope.js

function EventController($scope) {
    $scope.count = 0;
    $scope.$on('MyEvent', function() {
        $scope.count++;
    });
}

—————–>图片 23

本例是通过var todoList=this;让todoList代替了这个控制器。

3.$scope的生命周期

图片 24

创建—->注册监控—->检测模型的变化—->观察模型有没有“脏”—->自动销毁

通过定义todoList的属性和方法向外暴露这个控制器的可用属性和方法。

可以看见在html中是通过todoList属性的名字对其进行引用的。

其中{{}}代表数据绑定。

ng-model:表示把前台是数据绑定到控制器中,当然后台初始化有数据,也会显示在前台。

ng-submit:定义在form标签中,代码提交表单,也可以在button标签添加ng-click达到同样的效果。

ng-repeat:重复属性,会对需要遍历的元素生成对应个数的标签。

上述例子中就会生成对应todoList数目的span标签。

属性应用直接是todoList.todos。

方法的引用则为:todoList.addTodo()。

 

当然这只是其中一个暴露的方法。以后的篇章会介绍另外的。

 

相关文章