文档章节

Angular控制器之间的数据通信

梅气灶
 梅气灶
发布于 2015/12/10 15:22
字数 1590
阅读 189
收藏 3
点赞 0
评论 2

        angular作为在SPA开发中一个很强大的框架,数据操作是一大特点,而每个数据都有他们自己相应的作用域(即在自己的控制器内),那么,如何实现控制器之间的数据交互呢?归纳总结出来有如下几种:

控制器之间是父子关系——继承方式

        这样的交互方式是由于作用域的继承是基于js的原型继承方式的,所以需要分成两种情况,当作用域上的值(即你需要操作的数据)是基本类型的时候,修改父级作用域上面的值的同时会影响到子级作用域,但是修改子级作用域的值却不会改变父级作用域。另外一种情况是:作用域上的值是对象,这样无论是修改父级作用域还是子级作用域,两个都会改变!具体demo,可以查看我的上一篇文章。

基于广播机制的方式

        其实利用父子的继承方式已经能处理angular大部分的数据交互了,不过,当我们需要在兄弟节点进行数据交互的话,父子继承方式就显得那么有心无力了,那么这个时候就需要用到了我们的广播机制进行数据交互,具体我们来看下面的一个demo:

        先来看下控制器中的代码:

var routeApp = angular.module('routeApp', []);
    routeApp.controller('parentCtrl',['$scope',function($scope){
        $scope.parentname = "This is parent init name meichao";
        $scope.$on('firstChild', function(event,data){
            $scope.parentname = "This is firstChild change name";
            $scope.$broadcast('parent_to_secondCtrl', data);
        });
        $scope.$on('secondChild', function(event,data){
            $scope.parentname = "This is secondChild change name";
            $scope.$broadcast('parent_to_firstCtrl', data);
        });
    }]);
    routeApp.controller('firstChildCtrl',['$scope',function($scope){
        $scope.firstChidname = "This is firstChildCtrl init name";
        $scope.firstClick = function(){
            $scope.$emit('firstChild', $scope.firstChidname);
        }
        $scope.$on('parent_to_firstCtrl', function(event,data){
            $scope.firstChidname = data;
        });

    }]);
    routeApp.controller('secondChildCtrl',['$scope',function($scope){
        $scope.secondChidname = "This is secondChildCtrl init name";
        $scope.secondClick = function(){
            $scope.$emit('secondChild', $scope.secondChidname);
        }
        $scope.$on('parent_to_secondCtrl', function(event,data){
            $scope.secondChidname = data;
        });
    }]);

        再来看下我们的html中的代码:

<div ng-controller="parentCtrl">
        <div>{{parentname}}</div>
        <br>
        <div ng-controller="firstChildCtrl">
            <div>这里是firstChildCtrl中的可能会被改变的值:{{firstChidname}}</div>
            <br>
            <input type="text" ng-model="firstChidname">
            <div class="btn" ng-click="firstClick()">点我first</div>
        </div>
        <div ng-controller="secondChildCtrl">
            <div>这里是secondChildCtrl中的可能会被改变的值:{{secondChidname}}</div>
            <br>
            <input type="text" ng-model="secondChidname">
            <div class="btn" ng-click="secondClick()">点我second</div>
        </div>
    </div>

        我们一共写了有3个控制器,一个父级,两个子级(子级控制器互为兄弟),利用广播机制来实现firstChildCtrl控制器和secondChildCtrl控制器之间的数据交互,各控制器内都有一个函数用来触发$emit事件(像父级传送数据),然后在parentCtrl控制器中用$on来接收数据,进而像另外一个子控制器进行$broadcast广播,从而改变另外一个自控制器中的数据,以达到兄弟控制器之间的数据交互。

        具体效果可以自己写测试用例。

指令中的控制器与父级控制器之间的交互

        当我们自写指令的时候,也会有与父级控制器之间进行数据交互,来看一个demo:

<div ng-controller="parentCtrl">
        <div>{{parentname}}</div>
        <test/>
    </div>
    <script src="//cdn.bootcss.com/angular.js/1.3.9/angular.min.js"></script>
    <script>
        var routeApp = angular.module('routeApp', []);
        routeApp.controller('parentCtrl',['$scope',function($scope){
            $scope.parentname = "这里是父级控制器里面的内容";
        }]);
        routeApp.directive('test', function(){
            return {
                scope:true,
                template: '<div><div>{{parentname}}</div><input type="text" ng-model="parentname" /></div>',
                link: function($scope, iElm, iAttrs, controller) {
                    
                }
            };
        });
    </script>

        指令中的scope默认为false,那么我们创建的指令就会继承父作用域的一切属性和方法且不隔离,当我们在输入框中输入新的内容的时候,指令中的parentname和父作用域的parentname都会被改变,当我们把scope设置成true时,继承父作用域并且进行隔离:即在控制器中进行数据修改只会影响控制器中的parentname而不会影响到父作用域中的parentname,我们也可以将scope设置成独立作用域进行隔离且不继承,,来看设置成独立作用域后的demo:

<div ng-controller="parentCtrl">
        <div>{{parentname}}</div>
        <div test parentname="parentname"></div>
    </div>
    <script src="//cdn.bootcss.com/angular.js/1.3.9/angular.min.js"></script>
    <script>
        var routeApp = angular.module('routeApp', []);
        routeApp.controller('parentCtrl',['$scope',function($scope){
            $scope.parentname = "这里是父级控制器里面的内容";
        }]);
        routeApp.directive('test', function(){
            return {
                scope:{
                    parentname:'='
                },
                template: '<div><div>{{parentname}}</div><input type="text" ng-model="parentname" /></div>',
                link: function($scope, iElm, iAttrs, controller) {
                    
                }
            };
        });
    </script>

        可以看到,写法有些变化,scope:{parentname:'='}使用=实现数据的双向绑定,即在指令中的输入框中输入内容不仅会改变指令中的parentname也会改变父作用域中的parentname。当然,有数据的双向绑定,肯定也会有数据的单项绑定,请看demo:

<div ng-controller="parentCtrl">
        <div>{{parentname}}</div>
        <div test parentname="{{parentname}}"></div>
    </div>
    <script src="//cdn.bootcss.com/angular.js/1.3.9/angular.min.js"></script>
    <script>
        var routeApp = angular.module('routeApp', []);
        routeApp.controller('parentCtrl',['$scope',function($scope){
            $scope.parentname = "这里是父级控制器里面的内容";
        }]);
        routeApp.directive('test', function(){
            return {
                scope:{
                    parentname:'@'
                },
                template: '<div><div>{{parentname}}</div><input type="text" ng-model="parentname" /></div>',
                link: function($scope, iElm, iAttrs, controller) {
                    
                }
            };
        });
    </script>

        这样的话在输入框中输入内容,只会改变控制器中的parentname而不会改变父作用域中的parentname。

angular服务实现控制器之间数据交互

        在ng中,服务是一个单例,所以需要在服务中生成一个对象,该对象就可以利用依赖注入的方式将数据在所有的控制器中进行共享,下面请来看demo:

<div ng-controller="brotherCtrl_first">
        <input type="text" ng-model="test"/>
        <div class="btn" ng-click="change()">click me</div>
    </div>
    <div ng-controller="brotherCtrl_second">
        <div class="btn" ng-click="add()">my name {{name}}</div>
    </div>
    <script src="//cdn.bootcss.com/angular.js/1.3.9/angular.min.js"></script>
    <script>
    var routeApp = angular.module('routeApp', []);
    routeApp.factory('instance',function(){
        return {
            name:''
        }
    });
    routeApp.controller('brotherCtrl_first',['$scope','instance',function($scope, instance) {
        $scope.change = function(){
           instance.name = $scope.test;
       };
    }]);
    routeApp.controller('brotherCtrl_second', ['$scope','instance',function($scope, instance) {
        $scope.add = function() {
            $scope.name = instance.name;
        };
    }]);
    </script>

        在brotherCtrl_first控制器中的输入框中输入内容点击click me 按钮,这个时候会把输入框中的内容存放到服务中,然后我们在brotherCtrl_second控制器中点击按钮,则会从服务中把数据取出来传给name,从而实现数据的交互。

        在angular中的数据交互方式大自是这么几种,如果有说的不好的地方,还请指教。

© 著作权归作者所有

共有 人打赏支持
梅气灶
粉丝 30
博文 15
码字总数 20372
作品 0
杭州
前端工程师
加载中

评论(2)

梅气灶
梅气灶

引用来自“喝豆浆不用吸管”的评论

现在2就快出来了,学习1感觉都虚了
但是2的普及程度目前来说还是比较受限的,而且目前也还在学,至少先把1搞懂了,2再继续,哈哈
boogoogle
boogoogle
现在2就快出来了,学习1感觉都虚了
【前端】—聊聊我认识的Angular

前言 最近接触的项目前端用到了Angular框架,之前略有耳闻,从vue换到Angular,感觉东西差不多,还是要系统学习的,先来了解下。 正文 1、Angular 的发展 AngularJS 是一款来自Google的前端J...

zt15732625878 ⋅ 05/19 ⋅ 0

初学angular 看到网上有angular js 也有angular2 ,到angular官网发现最近版本是6了,那么现在大家说的angular js到底是什么啊?

初学angular 看到网上有angular js 也有angular2 ,到angular官网发现最近版本是6了,那么现在大家说的angular js到底是什么啊? angular2和现在官网的angular6 就是 angular js 只是版本不同...

Jordan裔 ⋅ 05/19 ⋅ 0

Angular 6.0正式版发布,都有哪些新功能

点击关注异步图书,置顶公众号 每天与你分享IT好书 技术干货 职场知识 在Angular 5发布半年之后,Angular 6在昨天正式发布,那么在这个版本有哪些新功能呢?新版本重点关注工具链以及工具链在...

异步社区 ⋅ 05/08 ⋅ 0

[Angular Material完全攻略] Day 01 - 开始 & 简介

转载 从Angular第2版正式release后,根据全球最大工程师讨论区StackOverflow的统计,从2016开始的Angular讨论度就不断窜升,甚至超越了React,直到了2017年,甚至摆脱了前一代Angularjs的阴影...

readilen ⋅ 05/21 ⋅ 0

Angular 6正式版发布,都有哪些新功能

在Angular 5发布半年之后,Angular 6在昨天正式发布,那么在这个版本有哪些新功能呢?新版本重点关注工具链以及工具链在 Angular 中的运行速度问题。除此之外,这次更新还包括框架包(@angu...

code_xzh ⋅ 05/05 ⋅ 0

AngularJS 的 Material Design 风格框架 - AngularJS Material

AngularJS Material 是 AngularJS 框架的谷歌 Material Design 标准的实现。AngularJS Material 包含一组丰富的、可重用、经过充分测试并可访问的 UI 组件。 针对 Angular 2 或更高版本的实现...

匿名 ⋅ 05/15 ⋅ 0

[Angular Material完全攻略] Day 02 - 环境设定 & 安装 & Hello World

今天我们将开始正式迈入Angular Material的世界,要学习使用Angular Material打造高品质及高质感的网页,当然要从安装Angular Material套件开始,本篇文章就来介绍基本的Angular Material安装...

readilen ⋅ 05/21 ⋅ 0

再谈angularJS数据绑定机制及背后原理—angularJS常见问题总结

Angular 的数据绑定采用什么机制,详述原理? 脏检查机制。阐释脏检查机制,必须先了解如下问题。 单向绑定(ng-bind) 和 双向绑定(ng-model) 的区别? ng-bind 单向数据绑定($scope ->...

634117608 ⋅ 04/19 ⋅ 0

Angular 的 Material Design 风格框架 - Angular Material

Material Design for Angular 是 Angular 官方团队开发的基于最新版本 Angular 的 Material Design 风格的框架,可和 Nest.js 搭配使用做全栈开发。 针对 Angular 1 版本的实现 https://www....

匿名 ⋅ 05/15 ⋅ 0

JavaScript MVW 框架 - AngularJS

Angular JS (Angular.JS) 是一组用来开发 Web 页面的框架、模板以及数据绑定和丰富 UI 组件。它支持整个开发进程,提供 Web 应用的架构,无需进行手工 DOM 操作。 AngularJS 很小,只有 60K,...

匿名 ⋅ 2011/01/20 ⋅ 44

没有更多内容

加载失败,请刷新页面

加载更多

下一页

磁盘管理—逻辑卷lvm

4.10-4.12 lvm 操作流程: 磁盘分区-->创建物理卷-->划分为卷组-->划分成逻辑卷-->格式化、挂载-->扩容。 磁盘分区 注: 创建分区时需要更改其文件类型为lvm(代码8e) 分区 3 已设置为 Linu...

弓正 ⋅ 8分钟前 ⋅ 0

Spring源码解析(六)——实例创建(上)

前言 经过前期所有的准备工作,Spring已经获取到需要创建实例的 beanName 和对应创建所需要信息 BeanDefinition,接下来就是实例创建的过程,由于该过程涉及到大量源码,所以将分为多个章节进...

MarvelCode ⋅ 28分钟前 ⋅ 0

a href="#"

<a href="#">是链接到本页,因为你有的时候需要有个链接的样式,但是又不希望他跳转,这样写,你可以把这个页面去试试

颖伙虫 ⋅ 35分钟前 ⋅ 0

js模拟栈和队列

栈和队列 栈:LIFO(先进后出)一种数据结构 队列:LILO(先进先出)一种数据结构 使用的js方法 1.push();可以接收任意数量的参数,把它们逐个推进队尾(数组末尾),并返回修改后的数组长度。 2....

LIAOJIN1 ⋅ 35分钟前 ⋅ 0

180619-Yaml文件语法及读写小结

Yaml文件小结 Yaml文件有自己独立的语法,常用作配置文件使用,相比较于xml和json而言,减少很多不必要的标签或者括号,阅读也更加清晰简单;本篇主要介绍下YAML文件的基本语法,以及如何在J...

小灰灰Blog ⋅ 44分钟前 ⋅ 0

IEC60870-5-104规约传送原因

1:周期循环2:背景扫描3:自发4:初始化5:请求6:激活7:激活确认8:停止激活9:停止激活确认10:激活结束11:远程命令引起的返送信息12:当地命令引起的返送信息13:文件传送20:响应总召...

始终初心 ⋅ 56分钟前 ⋅ 0

【图文经典版】冒泡排序

1、可视化排序过程 对{ 6, 5, 3, 1, 8, 7, 2, 4 }进行冒泡排序的可视化动态过程如下 2、代码实现    public void contextLoads() {// 冒泡排序int[] a = { 6, 5, 3, 1, 8, 7, 2, ...

pocher ⋅ 今天 ⋅ 0

ORA-12537 TNS-12560 TNS-00530 ora-609解决

oracle 11g不能连接,卡住,ORA-12537 TNS-12560 TNS-00530 TNS-12502 tns-12505 ora-609 Windows Error: 54: Unknown error 解决方案。 今天折腾了一下午,为了查这个问题。。找了N多方案,...

lanybass ⋅ 今天 ⋅ 0

IDEA反向映射Mybatis

1.首先在pom文件的plugins中添加maven对mybatis-generator插件的支持 ` <!-- mybatis逆向工程 --><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-ma......

lichengyou20 ⋅ 今天 ⋅ 0

4.10/4.11/4.12 lvm讲解 4.13 磁盘故障小案例

准备磁盘分区 fdisk /dev/sdb n 创建三个新分区,分别1G t 改变分区类型为8e 准备物理卷 pvcreate /dev/sdb1 pvcreate /dev/sdb2 pvcreate /dev/sdb3 pvdisplay/pvs 列出当前的物理卷 pvremo...

Linux_老吴 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部