这篇文章是用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. memcached--add使用

    memcached是一种管理内存的软件,来动态的分配机器的内存,将需要存储的数据以key-value(键值对)的形式存储在内存中. 1.memcached使用的存储算法是hash算法在内存中存储字符串 ...

  2. 3D echarts 点位报表展示

    一,准备工作1)获取Echarts 以下为官网推荐的几种获取 ECharts方式: 从官网下载界面选择你需要的版本下载,根据开发者功能和体积上的需求,我们提供了不同打包的下载,如果你在体积上没有要求, ...

  3. Python开发【第五篇】: 内置模块

    内容概要 二分查找.冒泡 random time os sys pickle json shelve re 1.二分查找和冒泡排序 01. 二分查找 二分查找也称折半查找(Binary Search) ...

  4. CDH 5.15.2 离线安装

    一.前置准备 1. 基础信息 1.1 机器 机器名 服务 hadoop1 主节点 hadoop2 data.task hadoop3 data.task 1.2 服务版本 服务 版本 cdh 5.15 ...

  5. 5分钟快速部署DataDraw数字绘

    经常有小伙伴问,有没有一款好用又免费的画图软件,画画流程图.UML.思维导图?今天就介绍一款开源的在线画图软件,满足各方面人的需求. DataDraw数字绘是一个在线线框图.流程图.网络图.组织结构图 ...

  6. CentOS java生成文件并赋予权限的问题

    2.检查文件是否允许: file.canExecute(); – return true, file is executable; false is not. file.canWrite(); – r ...

  7. 致远A8任意文件写入漏洞_getshell_exp

    近期爆出致远 OA 系统的一些版本存在任意文件写入漏洞,远程攻击者在无需登录的情况下可通过向 URL /seeyon/htmlofficeservlet POST 精心构造的数据即可向目标服务器写入任 ...

  8. C语言学习书籍推荐《嗨翻C语言(英文)Head First C》下载

    David Griffiths (作者), Dawn Griffiths (作者) Ever wished you could learn C from a book? Head First C pr ...

  9. 成功解决 org.mybatis.spring.MyBatisSystemException问题!!

    org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingExce ...

  10. springcloud-高可用部署

    1.场景描述 前端时间只简单介绍了下springcloud的高可用方案(springcloud高可用方案),今天详细介绍下如何实施springcloud的高可用部署. 2.解决方案 2.1 架构方案 ...