AngularJs MVC 详解
- 为什么在前端也需要MVC
1、代码规模越来越大,切分职责是大势所趋
2、为了复用
3、为了后期维护方便
MVC的目的是为了模块化和复用
- 前端实现MVC的困难
1、操作DOM必须等整个页面加载完
2、多个js如果出现依赖,需要程序员自己解决
3、js的原型继承
- Controller
需求:有一些功能,在各个控制器中都会用到,怎么办?
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en" ng-app="myApp"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <script type="text/javascript" src="../../jslib/angular.min-1.5.8.js"></script> 7 <script type="text/javascript" src="demo02.js"></script> 8 </head> 9 <body> 10 <div ng-controller="CommonController"> 11 <div ng-controller="Controller1"> 12 <p>{{greet.text}},AngularJs</p> 13 <button ng-click="test1()">test1</button> 14 </div> 15 <div ng-controller="Controller2"> 16 <p>{{greet.text}},AngularJs</p> 17 <button ng-click="test2()">test2</button> 18 </div> 19 <button ng-click="commonFn()">通用</button> 20 </div> 21 </body> 22 </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * Created by sherry on 16/8/3. 3 */ 4 5 var myApp = angular.module("myApp",[]); 6 myApp.controller("CommonController",function ($scope) { 7 $scope.commonFn = function () { 8 alert("这是通用功能"); 9 } 10 }); 11 myApp.controller("Controller1",function ($scope) { 12 $scope.greet = { 13 text:"Hello1" 14 }; 15 $scope.test1 = function () { 16 alert("test1"); 17 } 18 }); 19 myApp.controller("Controller2",function ($scope) { 20 $scope.greet = { 21 text:"Hello2" 22 }; 23 $scope.test2 = function () { 24 alert("test2"); 25 } 26 });
对于button,不管其隶属于哪个控制器,只要是在 CommonController 内的,就都能被调用 commonFn 方法就变成了两个“子”控制器的公共方法
如下:
<div ng-controller="CommonController"> <div ng-controller="Controller1"> <p>{{greet.text}},AngularJs</p> <button ng-click="test1()">test1</button> </div> <div ng-controller="Controller2"> <p>{{greet.text}},AngularJs</p> <button ng-click="test2()">test2</button> <button ng-click="commonFn()">通用</button> </div> </div>
但是:AngularJs中并不推荐这么做,AngularJs的最佳实践,是把公共部分抽取成Service,被Controller调用
Controller使用中的注意点:
1、不要试图去复用Controller,一般控制器只负责一小块视图【一般一个Controller负责的是一个业务逻辑,除非业务逻辑切分得足够细,否则不具备复用的可能】
2、不要在Controller中操作DOM,这不是控制器的职责【推荐将DOM操作使用指令来做,Controller中操作DOM的速度是非常低的】
3、不要在Controller里面做数据格式化,AngularJs有很好的表单控件
4、不要在Controller里面做数据过滤操作,AngularJs有$filter服务
5、一般来说,Controller是不会相互调用的,控制器之间的交互通过事件进行
- Model
<!DOCTYPE html> <html lang="en" ng-app> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" src="../../jslib/angular.min-1.5.8.js"></script> </head> <body> <input type="text" placeholder="输入..." ng-model="name"> <p>{{name}}</p> </body> </html>
通过 ng-model 标签,定义一个数据模型,实现双向绑定
- View
利用 driective 实现View的复用,就是定义一个指令,设置一个模板
AngularJs中的MVC,是借助$scope(作用域)实现的
- AngularJs作用域
$rootScope,根作用域,如果属性在当前控制器的$scope中找不到,就会依次向上去寻找,这点很像JavaScript中的原型继承
$scope是一个POJO
$scope提供了一些工具方法 $watch/$apply
$scope是表达式的执行环境
$scope是一个树型结构,与DOM标签平行
子$scope会继承父$scope上的属性和方法
每个AngularJs只有一个根$scope对象(一般位于ng-app上)
$scope可以传播事件,类似DOM事件,可以向上或向下传播
$scope不仅仅是MVC的基础,也是数据双向绑定的基础
使用 angular.element($0).scope() 获取当前$scope进行调试