这篇文章是用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. Spark学习之路(八)—— Spark SQL 之 DataFrame和Dataset

    一.Spark SQL简介 Spark SQL是Spark中的一个子模块,主要用于操作结构化数据.它具有以下特点: 能够将SQL查询与Spark程序无缝混合,允许您使用SQL或DataFrame AP ...

  2. Spark学习之路(六)—— 累加器与广播变量

    一.简介 在Spark中,提供了两种类型的共享变量:累加器(accumulator)与广播变量(broadcast variable): 累加器:用来对信息进行聚合,主要用于累计计数等场景: 广播变量 ...

  3. java创建对象的方式

    Java中创建对象的5种方式 作为Java开发者,我们每天创建很多对象,但我们通常使用依赖管理系统,比如Spring去创建对象.然而这里有很多创建对象的方法,我们会在这篇文章中学到. Java中有5种 ...

  4. 基于STM32之UART串口通信协议(三)接收

    一.前言 1.简介 回顾上一篇UART发送当中,已经讲解了如何实现UART的发送操作了,接下来这一篇将会继续讲解如何实现UART的接收操作. 2.UART简介 嵌入式开发中,UART串口通信协议是我们 ...

  5. [Vue 牛刀小试]:第十五章 - 传统开发模式下的 axios 使用入门

    一.前言 在没有接触 React.Angular.Vue 这类 MVVM 的前端框架之前,无法抛弃 Jquery 的重要理由,除了优秀的前端 DOM 元素操作性以外,能够非常便捷的发起 http 请求 ...

  6. 嵌入式物联网32 ARM linux 等创客学院学习视频共享给大家

    大家手机号登录学习链接即可观看   有坛友说手机号登录不上  具体自测  http://www.makeru.com.cn/live/1392_303.html?s=60220走进嵌入式http:// ...

  7. 设计模式-责任链模式(responsibility)

    责任链模式是行为模式的一种,该模式构造一系列的分别担当不同职责的类的对象(HeaderCar.BodyCar.FooterCar)来共同完成一个任务,这些类的对象之间像链条一样紧密相连. 角色和职责: ...

  8. Wannafly挑战赛1:Treepath(DFS统计)

    题目链接 题意 给出一棵树,问长度为偶数的路径数有多少. 思路 记录路径长度为奇数的数目和为偶数的数目,然后 n * (n-1) / 2 求和即可. #include <bits/stdc++. ...

  9. Java中session与application的异同

    客户端的session 其实是标记了你的请求来自哪个浏览器 问题1:永远都一样吗? 答:重启了浏览器,你的session id就改变了, 结果会导致,再无法取回原来在服务端保存的数据. 问题2:假设客 ...

  10. html select 可输入 可编辑

    <HTML> <HEAD> <META http-equiv='Content-Type' content='text/html; charset=gb2312'> ...