文档章节

Angular控制器之间的数据通信

梅气灶
 梅气灶
发布于 2015/12/10 15:22
字数 1590
阅读 189
收藏 3

        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感觉都虚了
第214天:Angular 基础概念

一、Angular 简介 1、 什么是 AngularJS - 一款非常优秀的前端高级 JS 框架 - 最早由 Misko Hevery 等人创建 - 2009 年被 Google 公式收购,用于其多款产品 - 目前有一个全职的开发团队继续开...

半指温柔乐
04/04
0
0
Angular 中得 scope 作用域梳理

$scope 的使用贯穿整个 Angular App 应用,它与数据模型相关联,同时也是表达式执行的上下文.有了 $scope 就在视图和控制器之间建立了一个通道,基于作用域视图在修改数据时会立刻更新 $scope,同...

顽Shi
2014/09/21
0
2
使用 AngularJS 的路由和模板实现单页应用 (Single Page)

概述 单页应用现在越来越受欢迎。模拟单页应用程序行为的网站都能提供手机/平板电脑应用程序的感觉。Angular可以帮助我们轻松创建此类应用 简单应用 我们打算创建一个简单的应用,涉及主页,...

oschina
2014/06/20
20.7K
1
登录失败,始终提示公司名称不存在

根据前端的输出错误应该是后端的服务接口没有启动,可是不知道怎么解决! 前端控制器输出错误如下: Load defined data api failed: Account.LoginAPI Error: [$injector:unpr] Unknown pro...

gread_369
2016/08/24
310
1
读书笔记“使用AngularJs开发下一代web应用”

国内一个挺好的读书笔记 http://www.sunzhongwei.com/angularjs.html 源码下载地址https://github.com/shyamseshadri/angularjs-book Angular SEO http://www.yearofmoo.com/2012/11/angula......

lilugirl
2014/01/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Iris框架

1、安装iris: $ go get -u github.com/kataras/iris 2、golang iris web项目热重启 # 安装rizla包 $ go get -u github.com/kataras/rizla # 热重启方式启动iris项目 $ rizla main.go......

Liens
15分钟前
3
0
初探sentinel实践思考

简单说下, sentinel的优势: 友好的控制面板,支持实时监控 多种限流。支持QPS限流,线程数限流,多种限流策略,如:直接拒绝,匀速模式(漏斗),冷启动(如设置限制1000,延迟10秒,那第一...

爱吃大肉包
17分钟前
4
0
转:MongDB分页查询

找到了一篇关于MongDB分页查询的博客 https://www.cnblogs.com/wslook/p/9275861.html

_liucui_
17分钟前
1
0
《边缘云计算技术及标准化白皮书》

12月12日,第八届中国云计算标准和应用大会在北京隆重召开,工业和信息化部党组成员,总工程师张峰先生,中国工程院副院长陈左宁女士,中国工程院院士沈昌祥先生,中国电子技术标准化研究院院...

阿里云官方博客
23分钟前
1
0
网站安全公司对于网站逻辑漏洞的修复方案分享

在网站安全的日常安全检测当中,我们SINE安全公司发现网站的逻辑漏洞占比也是很高的,前段时间某酒店网站被爆出存在高危的逻辑漏洞,该漏洞导致酒店的几亿客户的信息遭泄露,包括手机号,姓名...

网站安全
27分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部