一、控制器

首先列出几种我们平常使用控制器时的几种误区:

我们知道angualrJs中一个控制器时可以对应不同的视图模板的,但这种实现方式存在的问题是:

如果视图1和视图2根本没有任何逻辑关系,这样“控制器”的角色就会很尴尬,因为我们不可能把不同业务的数据模型都绑在同一个控制器中。

这种实现方式也存在一个问题是:如果控制器1和控制器2里面有2个方法是一模一样的怎么办?

<!doctype html>
<html ng-app>
<head>
<meta charset="utf-8">
</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>
<script src="js/angular-1.3.0.js"></script>
<script src="MVC3.js"></script>
</html>
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");
}
}

虽然子级控制器可以继承父级控制器的作用域及方法,但是我们一般不要去这样做,因为很可能会造成作用域的混乱。

正确的方式应该是这样的:我们把公共的方法抽离出来,放在公共的服务当中去,需要的时候从公共的服务中调取就好了。

在使用控制器时要注意几点:

1.不要去复用controller,一个控制器一般只负责一小块视图;(一般控制器处理的都是业务逻辑,业务逻辑的复用性一般很小)

2.不要在controller中操作DOM,这不是控制器的职责;(因为在 controller里面操作DOM会导致浏览器页面的重绘,这种代价是昂贵的)

3.一般不要在控制器里面做数据过滤操作,ng有$filter服务;

一般来说,Controller是不会相互调用的,控制器之间的交互会通过广播事件进行!

二、作用域

angularJs的MVC是借助$scope来实现的!

先来看一段代码:

<!doctype html>
<html ng-app>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="Scope1.css" />
</head>
<body>
<div class="show-scope-demo">
<div ng-controller="GreetCtrl">
Hello {{name}}!
</div>
<div ng-controller="ListCtrl">
<ol>
<li ng-repeat="name in names">
{{name}} from {{department}}
</li>
</ol>
</div>
</div>
</body>
<script src="js/angular-1.3.0.js"></script>
<script src="Scope1.js"></script>
</html>
function GreetCtrl($scope, $rootScope) {
$scope.name = 'World';
$rootScope.department = 'Angular';
} function ListCtrl($scope) {
$scope.names = ['Igor', 'Misko', 'Vojta'];
}

上面是两个不同的控制器,尽管ListCtrl控制器里面没有department,但它依然可以访问到department上的变量值。

神奇的$scope

1.$scope是一个对象;

2.$scope是表达式的执行环境(或者叫做作用域)(它是视图和控制器之间的胶水);

3.$scope提供了一些工具方法$watch()/$apply();  

(这个是实时检测对象属性变化的,在修改数据时会立刻更新$scope,当$scope发生变化时会立刻重新渲染视图);

(这两个方法虽然提供了监视数据模型变化的能力,将数据模型的变化在整个应用范围内进行通知,但一般我们不太会手动去调用$scope.$apply())

4.$scope是一个树形结构,与DOM标签平行;

5.子$scope会继承父$scope上的属性和方法;

6.每个angularJs应用只有一个$rootScope,一般位于ng-app上,$rootScope是所有$scope的最上层,

($rootScope也是angularJs中最接近全局作用域的对象,在$rootScope上附加太多业务逻辑并不是好主意,这与污染javaScript的全局作用域是一样的)

7.$scope也是实现双向数据绑定的基础;

8.可以用angular.element($0).scope()来进行调试;

9.$scope可以在控制器之间传播事件,可以向上$scope.$emit();也可以向下$scooe.$broadcast();

最后附一张$scope的生命周期图:

创建(创建一个作用域)——链接($scope对象会链接到视图中)——更新(脏值检查)——销毁(销毁作用域)

三、广播

3.1相关概念

通常作用域之间是不共享变量的,但作用域是有层次的,所以我们可以在作用域上通过广播来传递事件。

Angularjs中不同作用域之间可以通过组合使用$emit,$broadcast,,$on的事件广播机制来进行通信

$emit的作用是将事件从子级作用域传播至父级作用域,包括自己,直至根作用域。格式如下:$emit(eventName,args)

$broadcast的作用是将事件从父级作用域传播至子级作用域,包括自己。格式如下:$broadcast(eventName,args)

$on用于在作用域中监控从子级或父级作用域中传播的事件以及相应的数据。格式如下:$on(event,data)

上述说明中,eventName是需要广播的事件的名称,args传递的数据集合,$on 方法中的参数event是事件的相关对象,data是事件传播的数据。

3.2实例说明angularjs  $emit $broadcast $on的用法

<div ng-controller="ParentCtrl">
<div ng-controller="SelfCtrl">
<a ng-click="click()">click</a>
<div ng-controller="ChildCtrl"></div>
</div>
<div ng-controller="BroCtrl"></div>
</div>
var appControllers = angular.module('myApp', [])
appControllers.controller('SelfCtrl', ['$scope','$rootScope', function($scope, $rootScope){
var admin1 = {
'name': 'father',
'age': 45
};
var admin2 = {
'name': 'Lucy',
'age': 25
};
$scope.click = function() {
//事件的发送
//向子级控制器传递数据和事件,只有ChildCtrl能接受到广播,还有自己
$scope.$broadcast('to-child', admin2);
//向父级控制器传递数据和事件,只有parentCtrl能接收到广播,还有自己
$scope.$emit('to-parent', admin1);
//$rootScope发出的广播所有的作用域都可以接受到,可以用于同级之间进行广播
$rootScope.$broadcast('to-bro', '平级的数据');
}
}])
appControllers.controller('ParentCtrl', ['$scope', '$rootScope', function($scope, $rootScope){
//事件的接受
$scope.$on('to-parent', function(event, data){
console.log(event);
});
}])
appControllers.controller('ChildCtrl', ['$scope', '$rootScope', function($scope, $rootScope){
$scope.$on('to-child', function(event, data){
console.log(data);
});
}])
appControllers.controller('BroCtrl', ['$scope', '$rootScope', function($scope, $rootScope){
//$scope和$rootScope都可以接受到事件
$scope.$on('to-bro', function(event, data){
console.log(data);
});
$rootScope.$on('to-bro', function(event, data){
console.log(data);
});
}]);

angularjs 控制器、作用域、广播详解的更多相关文章

  1. AngularJS指令进阶 – ngModelController详解

    AngularJS指令进阶 – ngModelController详解 在自定义Angular指令时,其中有一个叫做require的字段,这个字段的作用是用于指令之间的相互交流.举个简单的例子,假如我 ...

  2. angularJS中$apply()方法详解

    这篇文章主要介绍了angularJS中$apply()方法详解,需要的朋友可以参考下   对于一个在前端属于纯新手的我来说,Javascript都还是一知半解,要想直接上手angular JS,遇到的 ...

  3. iOS 视图控制器转场详解

    iOS 视图控制器转场详解 前言的前言 唐巧前辈在微信公众号「iOSDevTips」以及其博客上推送了我的文章后,我的 Github 各项指标有了大幅度的增长,多谢唐巧前辈的推荐.有些人问我相关的问题 ...

  4. “全栈2019”Java第一百零五章:匿名内部类覆盖作用域成员详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. “全栈2019”Java第九十八章:局部内部类访问作用域成员详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  6. Spring MVC 学习)——控制器与@RequestMapping详解

    Spring MVC 学习总结(二)——控制器定义与@RequestMapping详解 一.控制器定义 控制器提供访问应用程序的行为,通常通过服务接口定义或注解定义两种方法实现. 控制器解析用户的请求 ...

  7. AngularJS开发指南9:AngularJS作用域的详解

    AngularJS作用域是一个指向应用模型的对象.它是表达式的执行环境.作用域有层次结构,这个层次和相应的DOM几乎是一样的.作用域能监控表达式和传递事件. 作用域的特点 作用域提供APIs($wat ...

  8. AngularJS中transclude用法详解

    这篇文章主要介绍了AngularJS中transclude用法,详细分析了transclude的具体功能.使用技巧与相关注意事项,需要的朋友可以参考下 本文实例讲述了AngularJS中transcl ...

  9. AngularJS开发指南10:AngularJS依赖注入的详解

    依赖注入是一种软件设计模式,用来处理代码的依赖关系. 一般来说有三种方法让函数获得它需要的依赖: 它的依赖是能被创建的,一般用new操作符就行. 能够通过全局变量查找依赖. 依赖能在需要时被导入. 前 ...

随机推荐

  1. Bundle使用&NSBundle

    之 前在初始化一个类的时候:TestViewController *viewcontroller=[[TestViewController alloc]initWithNibName:@"T ...

  2. 基于 HTML5 WebGL 的 3D 网络拓扑结构图

    现在,3D 模型已经用于各种不同的领域.在医疗行业使用它们制作器官的精确模型:电影行业将它们用于活动的人物.物体以及现实电影:视频游戏产业将它们作为计算机与视频游戏中的资源:在科学领域将它们作为化合物 ...

  3. CCF系列之ISBN号码(201312-2)

    试题名称: ISBN号码 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字.1位识别码和3位分隔符,其规 ...

  4. 数据结构 链式哈希表(Hash Table)的接口定义与实现分析(完整代码)

    链式哈希表的接口定义 关于哈希表与链式哈希表的描述可以参阅:http://www.cnblogs.com/idreamo/p/7990860.html 链式哈希表的操作与属性有:初始化.销毁.插入元素 ...

  5. 解决myeclipse10.1导出War包出错:Security Alert:Integrity check error

    解决myeclipse10.1导出War包出错:Security Alert:Integrity check error 解决myeclipse10.1不能导出war包报 ============== ...

  6. 单词拼写检查之cutoff距离

    前言 cutoff是一个比较冷门的概念,相比于DP经典算法的编辑距离,cutoff距离只局限于自然语言处理领域.提出cutoff距离的起因很简单,因为经典的编辑距离无法很好地衡量在字符串搜索过程中的编 ...

  7. Linux cp 移动的时候报错

    报错如下: cp: omitting directory `./nginx-1.12.1'   原因: 要移动的目录下还存在有目录   解决: cp -r 文件名 地址   注意: 这里的-r代表递归 ...

  8. 【转】nagios使用带url的check_http检测主机

    前一段时间在Cu论坛发现一个提问,问题是nagios关于检测主机http服务的.原帖地址http://bbs.chinaunix.net /forum.php?mod=viewthread&t ...

  9. jquery +/-小样式

    <script>部分 var num = 0; $(document).on('click','#add',function(){ _this = $(this); div = _this ...

  10. CSS——盒模型

    1.基本概念: 内容:(content)盒子里面的东西: 填充:(padding)怕盒子里面的东西损坏而添加的泡沫元素活抗震材料: 边框:(border)盒子本身 边界:(margin)则说明盒子的摆 ...