angular整理笔记一

    以下是归档内容,来自2015年angular学习笔记。学习自慕课网大漠穷秋。虽然已经过去了好久,但仍然记得老师当时的思路多清晰。棒棒哒。
    angular的4大核心特性
    MVC,模块化,指令系统,双向数据绑定是angular的四个最主要的核心特性。


    MVC

    什么是MVC,M数据模型,V视图层,负责展示,C业务逻辑和控制逻辑。职责清晰,代码模块化。


    为什么要用MVC?

    一定要理解这句话:MVC这是手段,终极目标是模块化和复用。不是因为要去实现MVC才去做东西,是因为要要去模块化和复用才去用MVC的。

    代码规模越来越大,切分职责是大势所趋
    为了复用:很多逻辑是一模一样的
    为了后期维护方便,修改一块功能不影响其他的功能。
    

    前端MVC的困难?

    浏览器加载js文件是要分成两段的,一段是下载,一段是执行,由于下面的一些问题,导致了前端MVC的实现不想后台那么方便。
    浏览器加载脚本–>加载完成后JIT编译执行。

    操作DOM的代码必须等整个页面加载完成
    多个JS文件之间如果出现互相依赖,程序猿必须自己解决
    js的原型继承也给前端编程带来了很多困难。
    

    关于C(controller)

    通过ng-controller指令来实现控制器。
    下面会将下面这种方法来声明控制器是不好的,因为没有实现模块化。

    1
    2
    3
    4
    5
    function hello($scope){
    $scope.textInput = {
    text:"cailidan"
    };
    }


    MVC–controller的实现方式1
    这样第一种的实现方式并不好,因为如果视图1和视图2并没有任何逻辑关系,控制器的角色就会很尴尬。也不符合我们代码的分离。无法应对大项目。


    MVC–controller的实现方式2
    这样是一种改进型的方法,我们把视图1和视图2的控制器分开,分别控制。但是如果我们视图1和视图2有两个一模一样的方法怎么办?就出现了下面的方式3.


    MVC–controller的实现方式3
    看起来时一种好方法,我们让控制器1和2继承这个公用控制器。但这种方法是不可以实行的。这在angular中是不允许,不可行的,不推荐的。


    MVC–controller的实现方式4
    通过sevice来做,把通用的东西抽象成服务,让控制器调用,而不是来继承这个通用控制器。


    Controller使用过程中的注意点

    不要试图去复用Controller,一般一个控制器只负责一小块试图
    不要在Controller中操作DOM,这不是controller的职责
    不要在Controller中做数据格式化,ng有很好用的表单
    不要在Controller里面做数据过滤,ng有$filter服务来过滤数据
    一般来说,Controller是不会互相调用的,控制器之间的交互会通过事件进行。
    

    对上面的几点的稍微解释:控制器是把业务逻辑放进去,业务逻辑一般不会大段大段的相同。操作DOM时指令的工作,而不是控制器的工作。数据过滤和数据格式化都可以用angular自己的服务和控件。Controller不要相互调用,否则耦合性太强。


    关于数据模型MODEL

    首先找ng-app,找到后,里面所有的东西归angular管,然后找这里面所有的指令编译。比如找到了ng-modal,这是挂在rootscope,在ng-app下面的任意一个都可以获得。

    虽然上面的例子不是angular推荐的,主要看内部的$scope里面的设置。这就是主要实现modal的方法。


    模块化

    不推荐的写法:

    1
    2
    3
    4
    5
    function hello($scope){
    $scope.textInput = {
    text:"cailidan"
    };
    }

    这样定义了很多很多的全局函数,肯定是不好的,而通过定义一个模块,然后在模块上生成控制器,这是angular的实现模块方法。注意写法,[“$scope”,function()]。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var myModule = angular.module("myModule",[]);
    myModule.directive("hello",function(){
    return {
    restrict:"E",
    template:"<div>cailidan</div>",
    replace:true
    }
    })


    angular一切都是从模块开始的,只有把模块定义好了,才能够在模块上调用service,controller,filter等等。就是首先就是定义模块。


    指令系统

    下面这个代码中,如果再html中写了hello就会被替换成cailidan。ng-app实际上就是angular的一个指令,相当于main。在任何一个单页中ng-app只能出现一次。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var myModule = angular.module("myModule",[]);
    myModule.directive("hello",function(){
    return {
    restrict:"E",
    template:"<div>cailidan</div>",
    replace:true
    }
    })

    上面也是一种如何复用View的方法。我们可以定义很多个不用的指令,然后在需要他们地方加载他们,这样也就达到了复用模板的目的。


    双向数据绑定

    单项数据绑定

    目前大多数前端框架都是实现单向数据绑定,jqueryUI,BackBone,Flex。单向数据绑定的过程是:首先是把模板写好,然后加上数据,数据可能是从后台读出来的。把模板和数据绑定在一起,生成html标签,然后插入到模板中,这样不好的地方是,html一旦生成完后就没法变了,当有新的数据来时,只能重新绑定生成。所以angular就实现了双向事件绑定。


    双向数据绑定

    核心想法是:视图和模型是对应的,当数据模型发生变化的时候,它希望视图自动更新,当视图发生变化的时候,数据模型也发生变化。这中间需要一种时间机制。比如表单中,视图会自动变化,当表单的视图发生变化时,就可以自动反应到数据模型。下面是一个实例。

    1
    2
    3
    4
    5
    <body ng-app>
    <input type="text" ng-model="textInput">
    <p>{{textInput}},hello</p>
    <script src="./js/angular-1.3.0.js"></script>
    </body>

    双大括号是用来取值的。当input里面发生变化时,ng-modal的值也会发生变化。


    具体的$scope解释

    angularJS的MVC都是通过作用域$scope实现的。
    看下这个$scope能实现什么。

    1
    2
    3
    4
    5
    6
    7
    function GreetCtrl($scope,$rootScope){
    $scope.name = "world";
    $root.department = "Angular";
    }
    function ListCtrl($scope){
    $scope.names = ["Igor","Misko","Vojta"];
    }

    这里$rootScope就是根作用域,整个的作用域就像一个树形结构一样。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <div ng-controller="GreetCtrl">
    Hello{{name}}
    </div>
    <div ng-controller="ListCtrl">
    <ol>
    <li ng-repeat = "name in names">
    {{name}} from {{department}}
    </li>
    </ol>
    </div>

    这里的department虽然不是在ListCtrl中定义的,但由于是全局作用域,所以根目录下所有的模块都能访问到。跟作用域链有点像,如果再自己的$scope里面没有,就一直往上找,一直到$rootScope为止。


    可以用插件来看到$scope的树形结构。

    $scope的生命周期

    首先是创建一个$scope,然后是注册一个监控,然后检测模型变化,然后观察模型,最后销毁(自动或手动)。