一、控制器

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

我们知道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. php对数组进行分页

      3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 ...

  2. Spring MVC 用post方式提交表单到Controller乱码问题,而get方式提交没有乱码问题

    在web.xml中添加一个filter,即可解决post提交到Spring MVC乱码问题 <!-- 配置请求过滤器,编码格式设为UTF-8,避免中文乱码--> <filter> ...

  3. Servlet--HttpSession接口,HttpSessionContext接口,Cookie类

    HttpSession接口 定义 public interface HttpSession 这个接口被 Servlet 引擎用来实现在 HTTP 客户端和 HTTP 会话两者的关联.这种关联可能在多外 ...

  4. Centos 7 安装 memcached

    一.准备工作: 安装之前确保你的系统上已经安装libevent和telnet· 1.测试是否安装telnet: # rpm -qa |grep telnet 如果显示结果为: telnet-0.17- ...

  5. 【转】C++易混知识点1: 指针常量和常量指针的区别,附有详细案例解释

    熟悉C++也已经有一些年头了,今天突然翻出当年浏览的书籍,对一些概念居然生疏了,指针常量和常量指针由于 指针 这一特殊的对象而变得难以区别.因此,在思考再三之后,决定写下该篇总结,加强对他们的区别: ...

  6. DRBD的主备安装配置

    drbd软件包链接:https://pan.baidu.com/s/1eUcXVyU 密码:00ul 1.使用的资源:1.1 系统centos6.9 mini1.2 两台节点主机node1.node2 ...

  7. spark头脑镜像

    思考是一件有意思的事情.遇到问题,思考出结论,那么脑子里面的过程是什么呢,或者脑子里面是什么呢.我一直认为,这团团的里面是一个模糊的n维空间.理解一个复杂的系统.公式.算法,都要在这个n维空间里具象化 ...

  8. python中用xpath匹配文本段落内容的技巧

    content = item.xpath('//div[@class="content"]/span')[0].xpath('string(.)') content = item. ...

  9. c# 实现mysql事务

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  10. 安装pcntl以实现php多进程

    pcntl 扩展包一般就在php源码的ext目录下. cd ./ext/pcntl /opt/server/php5/bin/phpize ./configure \ --with-php-confi ...