AngularJS使用$ rootScope作为数据存储

Chr*_*ins 58 angularjs

我对我的AngularJS应用程序有一个想法,我很好奇AngularJS社区是否会认为可以这样做...

简而言之,我正在连接到数据API并在页面上显示我的结果.我创建了一个角度服务,在$ rootScope.DataStore上创建数据存储.我还有一个服务方法,它使用API​​端点返回的数据更新DataStore.如果我使用DataStore.update('products')从我的控制器内部请求"products"API端点,这将使用我的产品数据更新$ rootScope.DataStore.products.现在,在视图/部分中,我需要做的就是说ng-repeat ="DataStore.products中的产品"来显示我的数据,并且我在哪个控制器范围并不重要.所以,本质上我的DataStore是我唯一的真相来源.

我觉得从这种方法中获得的东西很容易遵循语义和最小的控制器编码.因此,无论何时更新DataStore,任何绑定到DataStore的内容也都会更新.

这会给$ rootScope摘要周期带来太多负担,还是这只是一种奇怪的方式呢?或者它是一个非常棒的方式?:)欢迎任何评论.

Dan*_*Dan 89

这个问题在AngularJS常见问题解答中引用:

有时,您希望为整个应用程序提供全局数据.对于这些,您可以像任何其他范围一样注入$ rootScope并在其上设置值.由于范围继承自根范围,因此这些值可用于附加到ng-show等指令的表达式,就像本地$ scope上的值一样.

看来团队确实鼓励使用$rootScope这种方式,这个警告:

当然,全局状态很糟糕,你应该谨慎地使用$ rootScope,就像你希望用任何语言的全局变量一样.特别是,不要将它用于代码,只用于数据.如果您想在$ rootScope上添加一个函数,那么将它放在一个可以在需要的地方注入的服务并且更容易测试几乎总是更好.

相反,不要创建一个服务,其唯一目的是存储和返回数据位.

这不会对$digest循环施加太多负载(实现基本的脏检查以测试数据突变),这不是一种奇怪的做事方式.

编辑: 有关性能的更多详细信息,请参阅Misko(AngularJS dev)的答案:SO:数据绑定如何在AngularJS中运行? 特别注意性能部分.


Jor*_*leo 33

为了安抚所有各方,为什么不使用$ cacheFactory.这允许数据请求服务是无状态的,基本上只是一个getter和setter.我承认将数据保存在$ rootScope上或作为服务中的属性很方便,但感觉不对.使用$ cacheFactory也很简单.

首先创建一个缓存服务:

angular.module('CacheService', ['ng'])
    .factory('CacheService', function($cacheFactory) {
    return $cacheFactory('CacheService');
});
Run Code Online (Sandbox Code Playgroud)

在你的app.js中包含js文件,然后将其注入你的app声明中:

var MyApp = angular.module('MyApp', ['CacheService']);
Run Code Online (Sandbox Code Playgroud)

在服务中注入它,使用它如下:

'use strict'

MyApp.factory('HackerNewsService', function(CacheService) {
    return {
        getNews: function(key) {
            var news = CacheService.get(key);

            if(news) {
                return news;
            }

            return null;
        },
        setNews: function(key, value) {
            CacheService.put(key, value);
        },
        clearNews: function(key) {
            CacheService.put(key, '');
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

现在你需要做的就是在控制器中注入HackerNewsService,并通过调用我们在其上创建的方法来使用它.例如:

HackerNewsService.setNews('myArticle', {headline: 'My Article', body: 'This is the body'});
$scope.article = HackerNewsService.getNews('myArticle');
Run Code Online (Sandbox Code Playgroud)


Rub*_*rop 8

我的经验是使用$ rootScope存储我的应用程序中所有ngView常见的数据模型部分,是最方便的方法.

<div>{{mymodel.property}}</div>
Run Code Online (Sandbox Code Playgroud)

对我来说比我更可读和更短

<div>{{getPropertyModel()}}</div>
Run Code Online (Sandbox Code Playgroud)

用javascript

app.factory('MyModel', function(){
    return {
        getModel: function() { ... },
        setModel: function(m) { ... },
    }
});

app.controller('ctrl', ['$scope', 'MyModel', function($scope, MyModel){
    $scope.getPropertModel = function() {
        return MyModel.getModel().property;
    };
}]);
Run Code Online (Sandbox Code Playgroud)

如果使用服务或cachefactory,则html模板中对模型的每次访问都将成为一个函数,与访问rootScope的属性相比,它的可读性较差.使用$ rootScope可以减少代码,从而减少错误并减少测试.

当然,只有所有ngView的公共部分都存储在$ rootScope中.模型的其余部分存储在本地$ scope中.

函数上的监视也比对象属性慢.因此,性能方面,$ rootScope也更好.