这篇文章是用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. C语言实现Linux网络嗅探器

    C语言实现Linux网络嗅探器 0x01 实验简介 网络嗅探器是拦截通过网络接口流入和流出的数据的程序.所以,如果你正在浏览的互联网,嗅探器以数据包的形式抓到它并且显示.在本实验中,我们用 C 语言实 ...

  2. SqlServer导入大文件Sql

    sqlcmd -S "192.168.1.218" -U "sa" -P "1qaz~xsw2" -d "SispMain&quo ...

  3. Jquery实现搜索功能

    <script> //搜索功能 (function ($) { jQuery.expr[':'].Contains = function (a, i, m) { return (a.tex ...

  4. RabbitMq-安装篇

    嘿,大家好,今天更新的内容是rabbitMq的安装篇~~ windows下安装rabbitMq rabbitMq下载地址:点我下载 1.由于rabbitMq用erlang语言开发,所以安装rabbit ...

  5. python初识(3)

    bool 字符串 for循环 bool 数字非零全都是True 字符串非空全都是True 字符串 索引 从0开始 0 切片选取 [x:y] 左闭右开区间 [x:y:z] 选取x到y之间 每隔z选取一次 ...

  6. Codeforces 776C:Molly's Chemicals(思维)

    http://codeforces.com/problemset/problem/776/C 题意:给出一个有n个数的序列,还有一个k,问在这个序列中有多少个子序列使得sum[l, r] = k^0, ...

  7. mysql 终端命令

    1.打开数据库 /usr/local/MySQL/bin/mysql -u root -p 2.输入root密码 3.使用我的数据库 use mysql 4.查看表 desc table_name 5 ...

  8. SSM集合

    SSM集成   1. Spring和各个框架的整合 Spring目前是JavaWeb开发中最终的框架,提供一站式服务,可以其他各个框架整合集成 Spring整合方案 1.1. SSH ssh是早期的一 ...

  9. python 实现一个计算器功能

    #s = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )' #第 ...

  10. 深入理解C#的装箱和拆箱

    个人理解(本质): 封箱是把值类型转换为引用类型 拆箱是把引用类型转换为值类型 封箱是把值类型转换为System.Object类型,或者转换为由值类型实现的接口类型: 例如: struct Mystr ...