这篇文章是用markdown工具写的,有需要的可以使用vscode打开
 
# angularjs 控制器、组件之间的通信
## 一、基于事件的方式
此方式下,主要通过 angularjs 内置指令`$on`,`$emit`,`$broadcast`来实现
- $on:表示事件监听
- $emit:表示向父级以上的作用域触发事件
- $broadcast:表示向子级以下的作用域广播事件
### 1. 向下广播事件
```js
//父控制器
function father($scope) {
$scope.toChildren = function() {
$scope.$broadcast('toChildren', 'father to children');
}
}
//子控制器
function children($scope) {
$scope.$on('toChildren', function(e, data) {
console.log('父传过来的值', data);
});
}
```
### 2. 向上传播事件
```javascript
//子控制器
function children($scope) {
$scope.$emit('toFather', 'children to father');
}
//父控制器
function father($scope) {
$scope.$on('toFather', function(e, data) {
console.log('子传过来的值', data);
});
}
```
### 3. 同级作用域之间传播
一个子控制中向父作用域触发一个事件,然后在父作用域中监听事件,再广播给另一子作用域,这样通过事件携带参数,实现了数据经过父作用域,在同级作用域之间传播。
**注意:** 通过父元素作为中介进行传递,同级元素用的事件名不能一样,否则会进入死循环。
```js
//子控制器1
function children1($scope) {
$scope.toChildren2 = function() {
$scope.$emit('toChildren2', 'children1 to children2');
}
}
//父控制器
function father($scope) {
$scope.$on('toChildren2', function(e, data) {
$scope.$broadcast('toChildren', data);
});
}
//子控制器2
function children2($scope) {
$scope.$on('toChildren', function(e, data) {
console.log('children1传过来的值', data);
});
}
```
## 二、angularjs服务的方式
在 angularjs 中服务是一个单例,所以在服务中生成一个对象,该对象就可以利用依赖注入的方式在所有的控制器中共享
```js
var app = angular.module('myApp', []);
//服务
app.factory('instance', function(){
return {};
});
//控制器1
app.controller('MainCtrl', function($scope, instance) {
$scope.change = function() {
instance.name = $scope.test;
};
});
//控制器2
app.controller('sideCtrl', function($scope, instance) {
$scope.add = function() {
$scope.name = instance.name;
};
});
```
## 三、component中的bindings对象
官方并不推荐我们使用 "=" 进行数据绑定, 因为 "=" 是一种双向的数据绑定,这就意味着我们在 component 中去修改数据的时候,在它的父组件中的值也会被修改。
```js
bindings: {
hero: '<', //'<'单向数据绑定,'='双向数据绑定
comment: '@', //'@'字符串绑定,特别是在绑定的值不会更改的时候
onClick: '&' //函数,绑定的函数将作为component事件的回调函数
}
```
### 1. component与父组件数据之间的绑定
父组件
```html
<body ng-controller="MainCtrl as ctrl">
<h3>hero</h3>
<br>
<hero-detail hero='ctrl.hero'></hero-detail>
</body>
```
```js
angular.module('ComponentTestApp',[])
.controller('MainCtrl',function(){
this.hero = {
name:'Sunday'
}
});
```
子组件
```HTML
<h1>HeroName: {{$ctrl.hero.name}}</h1>
```
```javascript
angular.module('ComponentTestApp')
.component('heroDetail',{
templateUrl:'',
controller:HeroDetailController,
bindings:{
hero:'<'
}
});
```
### 2. component与父组件方法之间的绑定
父组件
```html
<body ng-controller="MainCtrl as ctrl">
<hero-detail on-log="ctrl.log(text)"></hero-detail>
</body>
```
```js
angular.module('ComponentTestApp',[])
.controller('MainCtrl',function(){
this.log = function(text){
console.log("输出的内容为: " + text);
}
});
```
子组件
```html
<input type="text" placeholder="被输出的内容" ng-model="text">
<br>
<button ng-click="onLog()">outputLog</button>
```
```js
function HeroDetailController($scope){
$scope.text = '';
var ctrl = this;
$scope.onLog = function(){
ctrl.onLog({text: $scope.text});
}
}
angular.module('ComponentTestApp')
.component('heroDetail',{
templateUrl:'',
controller:HeroDetailController,
bindings:{
onLog:'&'
}
});
```
**注意:** 在代码中我们通过 "&" 符号去绑定了一个方法 `onLog()`,该方法接收一个 `text` 参数,在参数进行传递的时候,是以 json 的形式进行传递的,这样我们在点击 `outputLog` 按钮的时候,就会输出我们在 `input` 中输入的内容。
# postMessage、iframe通信
## iframe通信
通常我们使用iframe直接在页面嵌套iframe标签指定的src就可以了
```html
<iframe name="myiframe" id="myiframe" src="external_file.html" frameborder="0" width="200" height="200" scrolling="no">
```
- name:规定 `iframe` 的名称。
- width:规定 `iframe` 的宽度。
- height:规定 `iframe` 的高度。
- src:规定在 `iframe` 中显示的文档的URL。
- frameborder:规定是否显示 `iframe` 周围的边框。 (0 为无边框,1 位有边框)。
- align:规定如何根据周围的元素来对齐 `iframe`。 (left,right,top,middle,bottom)。
- scrolling:规定是否在 `iframe` 中显示滚动条。 (yes,no,auto)
通常我们需要从URL获取相关字段,可以通过下面方法,然后做相关业务处理
```js
$scope.urlData = $location.search();
```
## postMessage通信
### 1. 父页面发送数据给子页面
```js
//获取iframe元素
iFrame = document.getElementById('myiframe')
//iframe加载完毕后再发送消息,否则子页面接收不到message
iFrame.onload = function(){
//iframe加载完立即发送一条消息
iFrame.contentWindow.postMessage('MessageFromIndex1','*');
}
```
```js
//回调函数
function receiveMessage ( event ) {
console.log( 'receiveMessage', event )
}
//监听message事件
window.addEventListener("message", receiveMessage, false);
```
- postMessage是挂载在window对象上的,所以等iframe加载完毕后,用iFrame.contentWindow获取到iframe的window对象,然后调用postMessage方法,相当于给子页面发送了一条消息
- postMessage方法第一个参数是要发送的数据,可以是任何原始类型的数据。
- postMessage方法第二个参数可以设置要发送到哪个url,如果当前子页面的url和设置的不一致,则会发送失败,我们设置为*,代表所有url都允许发送。
### 2. 子页面发送数据给父页面
```js
//给父页面发送消息,data为对象
window.parent.postMessage( {msg: 'MessageFromIframePage'}, '*');
```
```js
//回调函数
function receiveMessageFromIframePage (event) {
console.log('receiveMessageFromIframePage', event)
}
//监听message事件
window.addEventListener("message", receiveMessageFromIframePage, false);
```

angularjs通信以及postmessage与iframe通信的更多相关文章

  1. web通信之跨文档通信 postMessage

    index.html <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type&qu ...

  2. window.postMessage 在iframe父子页面数据传输

    介绍 https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage window.postMessage 发送方 接收方 示例 ...

  3. 轻量级通信引擎StriveEngine —— C/S通信demo(2) —— 使用二进制协议 (附源码)

    在网络上,交互的双方基于TCP或UDP进行通信,通信协议的格式通常分为两类:文本消息.二进制消息. 文本协议相对简单,通常使用一个特殊的标记符作为一个消息的结束. 二进制协议,通常是由消息头(Head ...

  4. 系统间通信(5)——IO通信模型和JAVA实践 下篇

    7.异步IO 上面两篇文章中,我们分别讲解了阻塞式同步IO.非阻塞式同步IO.多路复用IO 这三种IO模型,以及JAVA对于这三种IO模型的支持.重点说明了IO模型是由操作系统提供支持,且这三种IO模 ...

  5. Flex通信-与Java实现Socket通信实例

    Flex通信-与Java实现Socket通信实例  转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...

  6. SSL、TLS协议格式、HTTPS通信过程、RDP SSL通信过程(缺heartbeat)

    SSL.TLS协议格式.HTTPS通信过程.RDP SSL通信过程   相关学习资料 http://www.360doc.com/content/10/0602/08/1466362_30787868 ...

  7. 结束QQ即时通信垄断,开辟即时通信互联互通instantnet时代

    结束QQ即时通信垄断,开辟即时通信互联互通instantnet时代 蓬勃发展的即时通信产业 即时通信(IM)是指可以即时发送和接收互联网消息等的业务. 即时通信.就是瞬间把信息发送给对方,假设不是即时 ...

  8. html5 postMessage解决iframe跨协议跨域通信问题

    a.html有个iframe载入b.com/login.html,当login完成时通知a.html页面登录完成并传递UserName 1.a.html 监听消息 window.addEventLis ...

  9. Javascript使用postMessage对iframe跨域通信

    今天才发现原来有这么个好东西啊,跨域通信太方便了, 举个小栗子: 共两个页面, 页面1:www.a.com/a.html 页面2:www.b.com/b.html 实现目标:两个网站页面实现跨域相互通 ...

随机推荐

  1. 解决kali linux 2016.2实体机安装后root用户没有声音

    Kali Linux系统默认状态下,root用户是无法使用声卡的,也就没有声音.启用的方法如下:(1)在终端执行命令:systemctl --user enable pulseaudio (2)在/e ...

  2. lunix杂记_scp与vi编辑器

    1.scp命令,复制其它服务器资源 scp 用户名@192.168.0.9:/usr/local/apache-tomcat-7.0.68 ./ scp -f  username@192.168.0. ...

  3. Unity Shader 屏幕后效果——边缘检测

    关于屏幕后效果的控制类详细见之前写的另一篇博客: https://www.cnblogs.com/koshio0219/p/11131619.html 这篇主要是基于之前的控制类,实现另一种常见的屏幕 ...

  4. .gitignore 的简单实用

    a: 在工作目录下右键点击使用git命令行(GitBash) b: 输入 touch .gitignore 命令,此时会在工作目录下生成一个“.gitignore”的文本文件 注:touch在git里 ...

  5. C++ luogu1352没有上司的舞会 from_树形DP

    luogu1352没有上司的舞会 分析(树形DP模板题): 没学树形DP的,看一下. 把该题抽象到一颗树中,设i的下属就是他的儿子,则有两种情况: 如果i参加,他的儿子就不能参加. 如果i不参加,他的 ...

  6. 寻觅Azure上的Athena和BigQuery(一):落寞的ADLA

    AWS Athena和Google BigQuery都是亚马逊和谷歌各自云上的优秀产品,有着相当高的用户口碑.它们都属于无服务器交互式查询类型的服务,能够直接对位于云存储中的数据进行访问和查询,免去了 ...

  7. Azure中国CDN全球覆盖功能初探

    在不久前的4月初,Azure中国官网上简短地发布了其CDN中“标准版 Zone 2”功能.一开始笔者尚有些摸不着头脑,这个“Zone 2”具体指的是什么呢?好在后来官网更新了信息描述如下: 这下就比较 ...

  8. 【POJ - 3050】Hopscotch (dfs+回溯)

    -->Hopscotch 这接写中文了 Descriptions: 奶牛们以一种独特的方式玩孩子们的跳房子游戏. 奶牛们创造了一个5x5的格子 他们熟练地跳上其中的一个格子,可以前后左右地跳(不 ...

  9. 9.22考试 crf的视察 题解

    这道题当时第一反应就是一道典型的NOIP第一题的难度,绝对要A掉,不然分数一定会被拉开. 然后就开始分析,暴力是一开始想的是用二维树状数组打加上暴力枚举长度,然而这道题满足二分性质,所以时间复杂度就是 ...

  10. ASP.NET CORE配置用户密码验证

    在 class Startup 中配置 public void ConfigureServices(IServiceCollection services) { services.AddDbConte ...