AngularJS(三)——在多个AngularJS controller之间共享数据


MVC中,为了方便维护,针对不同业务会使用不同的controller。有时我们需要在不同的controller中共享数据,本文旨在解决这一问题。

1. 使用$rootScope直接绑定

AngularJS中有一个$rootScope对象,它是AngularJS中最接近全局作用域的对象,是所有$scope对象的最上层,可以简单理解为BOM中的window对象或Node.js中的global对象。最简单的方式是直接将要共享的数据绑定到$rootScope对象中:

<!DOCTYPE html>
<html ng-app="exampleApp">
<head>
    <meta charset="utf-8">
    <title>Share Between Ctrls</title>
    <script src="lib/angular.js"></script>
    <link href="css/bootstrap.min.css" rel="stylesheet" />
    <link rel="stylesheet" href="css/bootstrap-responsive.min.css">
    <script>
        var app = angular.module("exampleApp", []);
        app.controller("FirstController", function($rootScope, $scope) {
            $scope.shareObject = function (obj) {
                $rootScope.person = obj || {};
            };
        });

        app.controller("SecondController", function($rootScope, $scope) {
            $scope.reportData = function() {
                var reportString = "",
                    person = $rootScope.person || {};
                for(var i in person) {
                    reportString += "person‘s " + i + " is " + person[i] + "\n";
                }
                alert(reportString);
            };
        });
    </script>
</head>
<body>
    <div class="well" ng-controller="FirstController">
        <input type="text" ng-model="person.name" placeholder="Input Your Name" />
        <input type="text" ng-model="person.age" placeholder="Input Your Age" />
        <input type="text" ng-model="person.sex" placeholder="Input Your Sex" />
        <button class="btn btn-primary" ng-click="shareObject(person)">Share Data</button>
    </div>
    <div class="well" ng-controller="SecondController">
        <button class="btn btn-primary" ng-click="reportData()">Report Data</button>
    </div>
</body>
</html>

整个效果如图-1 ~ 图-4所示:

图-1 页面加载完毕

图-2 第一次点击"Report Data"按钮

图-3 填写信息,点击"Share Data"按钮

图-4 再次点击"Report Data"按钮

这样做解决了问题,在需要共享的数据量较少时可以采用,但因为会污染全局作用域,因此十分不推荐使用这种方法。

2. 使用$scope事件机制

$scope可以向其他$scope广播或发送事件,其他$scope监听事件并处理,从而实现通信,也就是说可以通过$scope事件机制实现不同controller之间的数据共享。$scope事件机制包括以下三种方法:

表-1 有关$scope事件机制的三个方法

其中,$broadcast(name, args)为父级$scope向子级$scope发送事件,$emit(name, args)为子级$scope向父级$scope发送事件,$on(name, handler)为监听事件的函数,handler参数为对事件进行处理的函数,该函数包含两个参数:event和args,分别为事件对象和发送事件时传递的args参数。

这里我们不存在controller的嵌套,所有的$scope为同级,需要使用“祖宗级”$rootScope进行广播。有关controller嵌套和继承的问题会在之后的博文中讲到。

使用$scope事件机制处理数据共享的JS代码如下所示,由于HTML代码与之前相同,故省略:

...
<script>
    var app = angular.module("exampleApp", []);
    app.controller("FirstController", function($rootScope, $scope) {
        $scope.person = {};
        $scope.shareObject = function (obj) {
            obj = obj || {};
            //将事件以"ShareObjectEvent"为名进行广播
            $rootScope.$broadcast("ShareObjectEvent", obj);
        };
    });

    app.controller("SecondController", function($scope) {
        //监听"ShareObjectEvent"事件
        $scope.$on("ShareObjectEvent", function(event, args) {
            person = args;
        });
        $scope.reportData = function() {
            var reportString = "";
            for(var i in person) {
                reportString += "person‘s " + i + " is " + person[i] + "\n";
            }
            alert(reportString);
        };
    });
</script>
...

最终实现的效果和使用$rootScope直接绑定完全相同。

3. 使用service共享数据

...
<script>
    var app = angular.module("exampleApp", []);
    //需要将DataShareService注入
    app.controller("FirstController", function($scope, DataShareService) {
        $scope.person = {};
        $scope.shareObject = function (obj) {
            //赋值
            DataShareService.shareObject = obj;
        };
    });

    //需要将DataShareService注入
    app.controller("SecondController", function($scope, DataShareService) {
        var person = {};
        $scope.reportData = function() {
            var reportString = "",
                person = DataShareService.shareObject; //取值
            for(var i in person) {
                reportString += "person‘s " + i + " is " + person[i] + "\n";
            }
            alert(reportString);
        };
    });

    //自定义service,在多个controller之间共享数据
    app.factory("DataShareService", function() {
        //无需定义其他变量,无需return
    });
    <!-- 
         这里的
         app.factory()
         可以替换为
         app.constant()
         app.value()
         app.service()
     -->
</script>
...

最终实现的效果和使用$rootScope直接绑定完全相同。有关最后app.factory()的替换问题可以参考之前的一篇博客,使用AngularJS自定义service,有兴趣的读者可以自己试验一下。

完。



本文出自 “细桶假狗屎” 博客,请务必保留此出处http://xitongjiagoushi.blog.51cto.com/9975742/1684429

时间: 2024-10-20 04:32:08

AngularJS(三)——在多个AngularJS controller之间共享数据的相关文章

angulajs 如何在controller 之间共享数据

当在一个controller中 通过设置$scope的数据,来影响其它control的范围时,可以使用$rootScope 举个例子: 在一个control A范围内设置 mainApp.controller('menuController', function($scope,$rootScope) {        $rootScope.menus={}        $rootScope.menus.showWelcome = false;        $rootScope.menus.s

【MVC架构】——怎样利用Json在View和Controller之间传递数据

在MVC架构中,尽管非常多东西和三层非常相似,可是也有非常大的差别.就比方传递数据.在三层架构中,传递数据就仅仅要一层返回,另外一层用同样类型的变量来接收即可了.在MVC中,事实上原理是一样的,Controller中的方法返回Json字符串.然后View来接收.或者反过来,不同的就是这之间须要一个序列化和反序列化的过程. 本文就简介利用Json在View和Controller之间传递数据的一个方面,大致从双方面介绍,一是什么是Json,二是怎样实现. 什么是Json 一.概念 百度百科说:JSO

mvc如何使用JavaScript在view和controller之间传递数据

在一般的BS项目开发中,我们经常需要在前台和后台之间传递数据,mvc架构中,也需要在view和controller之间传递数据,那么我们应该如何实现呢? view想controller传递数据:view中代码 <li>@Html.ViewComponent().WfSaveLink(Model).Id("saveToLink").OnBeforeDo("externalData")</li> <scriptlanguage="

多线程(三) 实现线程范围内模块之间共享数据及线程间数据独立(ThreadLocal)

ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.JDK 1.2的版本中就提供java.lang.ThreadLocal,使用这个工具类可以很简洁地编写出优美的多线程程序,ThreadLocal并不是一个Thread,而是Thread的局部变量. 1.下图和辅助代码解释ThreadLocal的作用和目的:用于实现线程内的数据共享,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另外一份数据. 2.每个线程调用全局ThreadLocal

不同App之间共享数据

我们知道iOS由于沙盒的存在,应用程序不能越过自己的区域去访问别的存储空间的内容,不过可能有许多场景我们需要在应用程序之间共享数据,比如多个应用共用用户名密码进行登录等.虽然我们不能直接通过文件系统来共享数据,不过还是有些方法可以实现. 这里,我们新建两个工程,T1:负责写数据,T2:负责读数据. 方法一:UIPasteboard 剪贴板是应用程序之间传递数据的简单方式,建议不要使用全局的粘贴板,而是自己根据名字创建一个新的粘贴板,防止其它地方全局拷贝的影响.然后把需要共享的内容复制到粘贴板,粘

Android Content Provider在应用程序之间共享数据的原理分析

本文参考Android应用程序组件Content Provider在应用程序之间共享数据的原理分析http://blog.csdn.net/luoshengyang/article/details/6967204和<Android系统源代码情景分析>,作者罗升阳. 0.总图流程图如下: 总体类图: 1.MainActivity进程向AriticlesProvider进程发送IContentProvider.QUERY_TRANSACTION 如图:第一步 ~/Android/framework

Spring Batch学习笔记&mdash;&mdash;steps之间共享数据

名词说明: 上下文: 执行: 执行上下文: 案例: 警告:一旦steps共享数据,这些数据就会把这些steps连接起来.努力使steps独立.如果你实在是不能独立他们,才使用下面的技术.你应该把数据共享作为steps不能独立的后备方案. 1 数据共享方式: a step存储共享数据到数据库,receiving step从数据库读取他们 Execution context(执行上下文): 使用Spring  Batch execution context 作为data容器.a step往上下文写数

Android多线程研究(5)——线程之间共享数据

一.如果是每个线程都执行相同的代码,则可以使用同一个Runnable来实现共享 public class MultiThreadShareData { public static void main(String[] args) { new Thread(new ShareData()).start(); new Thread(new ShareData()).start(); } static class ShareData implements Runnable{ private int j

两个Activity之间共享数据、互相访问的另一种方式的实现

本帖最后由 勇敢的心_ 于 2010-9-29 11:51 编辑本人从windows编程转过来学习Android开发,一直在想如果两个Activity之间能够像C#或delphi中的Form一样,可以直接访问其成员(字符.数值.成员对象等),并能调用其公开的方法,那应该比用Intent来传递数据直接方便的多,于是偿试了如下办法,测试基本没有问题,发出来大家讨论一下.本人学习android不久,幼稚的地方希望大家不要见笑原理:假设有两个Activity:ActivityMain 和 Activit