如何在Angular中使用$ rootScope存储变量?


217

如何$rootScope在以后要在另一个控制器中访问的控制器中存储变量?例如:

angular.module('myApp').controller('myCtrl', function($scope) {
  var a = //something in the scope
  //put it in the root scope
});

angular.module('myApp').controller('myCtrl2', function($scope) {
  var b = //get var a from root scope somehow
  //use var b
});

我该怎么做?


1
您应该在控制器中注入$ rootScope并将其用作简单的javascript
Ajay Beniwal13

30
$ rootScope不是执行此操作的正确方法。使变量在多个控制器之间可用几乎就是服务的用途。
史蒂夫

11
@Steve:角的常见问题说“不创建的唯一目的在生活中对数据的存储和回位的服务”这把太多的负载上的$消化周期..
Marwen特拉贝尔西

如果无法将控制器注入服务中,如何从您所说的服务中将变量发送给其他控制器?我认为没有办法让它正常工作...在这里感谢您的见解..
2015年

2
好吧,因为它不能注射,所以您需要一个注射器
。– Xsmael

Answers:


248

在根范围内设置的变量可通过原型继承供控制器范围使用。

这是@Nitish演示的修改后的版本,显示了更清晰的关系:http : //jsfiddle.net/TmPk5/6/

注意,在模块初始化时设置了rootScope的变量,然后每个继承的作用域都有自己的副本,可以独立设置(该change函数)。另外,rootScope的值也可以更新(中的changeRs函数myCtrl2

angular.module('myApp', [])
.run(function($rootScope) {
    $rootScope.test = new Date();
})
.controller('myCtrl', function($scope, $rootScope) {
  $scope.change = function() {
        $scope.test = new Date();
    };

    $scope.getOrig = function() {
        return $rootScope.test;
    };
})
.controller('myCtrl2', function($scope, $rootScope) {
    $scope.change = function() {
        $scope.test = new Date();
    };

    $scope.changeRs = function() {
        $rootScope.test = new Date();
    };

    $scope.getOrig = function() {
        return $rootScope.test;
    };
});

7
加1表示……嗯……实际上回答了OP的问题。(尽管@MBielski和其他人是正确的)。
说唱时间

如果我执行$scope.test = 'Some value'$rootScope.test更改也会一样吗?
艾伦·利纳托茨

@AllenLinatoc不,虽然它们的范围$rootScope 是全局的(在所有控制器上),但$scope它们对于控制器而言仍然是本地的,它们不是两个不同的对象。如果 $scope.test在两个不同的控制器中使用,请知道它们是两个不同的变量,是否$rootScope.test 在所有控制器中都是相同的变量
Xsmael

我假设您不想出于其他原因使用$ rootScope而不使用其他语言的全局变量?
Zypps987

我们可以在一个应用程序中创建多少个rootscope变量?
周杰伦'18

161

控制器/控制器之间共享数据是工厂/服务的优势所在。简而言之,它的工作原理是这样的。

var app = angular.module('myApp', []);

app.factory('items', function() {
    var items = [];
    var itemsService = {};

    itemsService.add = function(item) {
        items.push(item);
    };
    itemsService.list = function() {
        return items;
    };

    return itemsService;
});

function Ctrl1($scope,items) {
    $scope.list = items.list; 
}

function Ctrl2($scope, items) {
    $scope.add = items.add;
}

您可以在此小提琴中看到一个有效的示例:http : //jsfiddle.net/mbielski/m8saa/


49
+1 $rootScope当我们拥有诸如服务和工厂之类的东西时,不应将其用于共享变量。
jjperezaguinaga

74
好吧,Angular FAQ在页面底部这样说:“相反,不要创建一个服务,其唯一的目的就是存储和返回数据。” 参见:docs.angularjs.org/misc/faq
Oytun,2014年

11
这是一个简单的例子。我相信他们说不要在一个控制器中只有一项服务。我无法统计开发Angular的员工有多少个地方特别指出服务是在控制器之间传递数据的官方方式。看看邮件列表,询问各种Angular照明器,看看会得到什么。我可能还会注意到,您的引文位于标题为“ $ rootScope存在,但可用于邪恶的部分”的底部。将数据从一个控制器传递到另一个控制器是邪恶的。
MBielski 2014年

1
但是,如果您需要在两个不同的视图/控制器中循环您的项目,则需要首先在控制器中复制数据以将其提供给视图?(我相信这是$ rootScope解决的问题)
Thomas Decaux 2014年

1
由开发人员决定是否应该使用服务还是使用rootScope快速修复程序,对于某些情况,全局范围是一种便利,并且是一种方便的方法-我认为这就是Angular文档要说的。让我们保持编程的艺术水平,而不是完全成为MVC的机器人。如果您需要一个控制器来了解更改,则可以使用上述服务,并使用$ watch变量,但是就目前情况而言,它实际上并不是控制器之间的通信。
着陆

21
angular.module('myApp').controller('myCtrl', function($scope, $rootScope) {
   var a = //something in the scope
   //put it in the root scope
    $rootScope.test = "TEST";
 });

angular.module('myApp').controller('myCtrl2', function($scope, $rootScope) {
   var b = //get var a from root scope somehow
   //use var b

   $scope.value = $rootScope.test;
   alert($scope.value);

 //    var b = $rootScope.test;
 //  alert(b);
 });

演示


因此,在Angular中,您通常不使用var吗?
trysis

1
它取决于条件。如果要显示为html,则需要使用var,否则可以使用var
Nitish Kumar

范围是DOM的东西吗?
trysis

1
这可能已经晚了,但是对于任何后来者来说,作用域是每个AJS文档中视图和控制器之间的粘合剂。作用域不直接引用DOM。那是做什么的呢?这里是更详尽的文档 docs.angularjs.org/guide/scope
yantaq 2014年

9

我发现没有理由这样做$ scope.value = $ rootScope.test;

$ scope已经是$ rootScope的原型继承。

请看这个例子

var app = angular.module('app',[]).run(function($rootScope){
$rootScope.userName = "Rezaul Hasan";
});

现在,您可以将此作用域变量绑定到应用程序标记中的任何位置。


6

首先将$ rootScope中的值存储为

.run(function($rootScope){
$rootScope.myData = {name : "nikhil"}
})

.controller('myCtrl', function($scope) {
var a ="Nikhilesh";
$scope.myData.name = a;
});

.controller('myCtrl2', function($scope) {
var b = $scope.myData.name;
)}

$ rootScope是所有$ scope的父级,每个$ scope都会收到$ rootScope数据的副本,您可以使用$ scope本身进行访问。


3

如果只是“访问其他控制器”,则可以使用角度常数,这样做的好处是;您可以添加一些全局设置或要在整个应用程序中访问的其他内容

app.constant(‘appGlobals’, {
    defaultTemplatePath: '/assets/html/template/',
    appName: 'My Awesome App'
});

然后像这样访问它:

app.controller(‘SomeController’, [‘appGlobals’, function SomeController(config) {
    console.log(appGlobals);
    console.log(‘default path’, appGlobals.defaultTemplatePath);
}]);

(未测试)

更多信息:http : //ilikekillnerds.com/2014/11/constants-values-global-variables-in-angularjs-the-right-way/



1

有多种方法可以实现这一目标:

1.添加$rootScope.run方法

.run(function ($rootScope) {
    $rootScope.name = "Peter";
});

// Controller
.controller('myController', function ($scope,$rootScope) {
    console.log("Name in rootscope ",$rootScope.name);
    OR
    console.log("Name in scope ",$scope.name);
});

2.创建一项服务,然后在两个控制器中访问它。

.factory('myFactory', function () {
     var object = {};

     object.users = ['John', 'James', 'Jake']; 

     return object;
})
// Controller A

.controller('ControllerA', function (myFactory) {
    console.log("In controller A ", myFactory);
})

// Controller B

.controller('ControllerB', function (myFactory) {
    console.log("In controller B ", myFactory);
})
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.