【问题标题】:Are Angularjs services singleton?Angularjs 服务是单例的吗?
【发布时间】:2014-02-25 02:34:56
【问题描述】:

reference我读到:

最后,重要的是要意识到所有 Angular 服务都是 应用程序单例。这意味着只有一个实例 每个注入器都有一个给定的服务。

但是用这个简单的代码似乎不是单例

'use strict';
            angular.module('animal', [])
                .factory('Animal',function(){
                    return function(vocalization){
                        return {
                            vocalization:vocalization,
                            vocalize : function () {
                                console.log('vocalize: ' + this.vocalization);
                            }
                        }
                    }
                });    
                angular.module('app', ['animal'])
                    .factory('Dog', function (Animal) {
                        return Animal('bark bark!');
                    })
                    .factory('Cat', function (Animal) {
                        return Animal('meeeooooow');
                    })
                .controller('MainCtrl',function($scope,Cat,Dog){
                     $scope.cat = Cat;
                     $scope.dog = Dog;
                     console.log($scope.cat);
                     console.log($scope.dog);
                    //$scope.cat = Cat;
                });

我有点困惑,你能解释一下这是怎么回事吗?

更新 1 也许我不是棚子里最锋利的工具 但是在@Khanh 回复之后会更好 参考文献中的解释不是很清楚。

更新 2

'use strict';
            angular.module('animal', [])
                .factory('Animal',function(){
                        return {
                            vocalization:'',
                            vocalize : function () {
                                console.log('vocalize: ' + this.vocalization);
                            }
                        }

                });
                angular.module('dog', ['animal'])
                    .factory('Dog', function (Animal) {
                        Animal.vocalization = 'bark bark!';
                        Animal.color = 'red';
                        return Animal;
                    });

                angular.module('cat', ['animal'])
                   .factory('Cat', function (Animal) {
                        Animal.vocalization = 'meowwww';
                        Animal.color = 'white';
                        return Animal;
                    });
                 angular.module('app', ['dog','cat'])
                .controller('MainCtrl',function($scope,Cat,Dog){
                     $scope.cat = Cat;
                     $scope.dog = Dog;
                     console.log($scope.cat);
                     console.log($scope.dog);
                    //$scope.cat = Cat;
                });

BOOM 这是一个单例!

更新 3

如果你喜欢

'use strict';
            angular.module('animal', [])
                .factory('Animal',function(){
                    return function(vocalization){
                        return {
                            vocalization:vocalization,
                            vocalize : function () {
                                console.log('vocalize: ' + this.vocalization);
                            }
                        }
                    }
                });    
                angular.module('app', ['animal'])
                    .factory('Dog', function (Animal) {
                        function ngDog(){
                            this.prop = 'my prop 1';
                            this.myMethod = function(){
                                console.log('test 1');
                            }
                        }
                        return angular.extend(Animal('bark bark!'), new ngDog());
                    })
                    .factory('Cat', function (Animal) {
                        function ngCat(){
                            this.prop = 'my prop 2';
                            this.myMethod = function(){
                                console.log('test 2');
                            }
                        }
                        return angular.extend(Animal('meooow'), new ngCat());
                    })
                .controller('MainCtrl',function($scope,Cat,Dog){
                     $scope.cat = Cat;
                     $scope.dog = Dog;
                     console.log($scope.cat);
                     console.log($scope.dog);
                    //$scope.cat = Cat;
                });

有效

【问题讨论】:

  • 引用不存在了

标签: angularjs


【解决方案1】:

它是单例的,只有一个对象,但是被注入到很多地方。 (对象通过引用方法传递)

你所有的Animal 都是对象指针,指的是同一个动物对象,在你的情况下这是一个函数。 你的CatDog 是这个函数构造的对象。

【讨论】:

  • 因为我有 php 背景,这对我来说听起来有点奇怪。如果在 php 应用程序中我使用 db 单例连接,我只能有一个连接,这就是为什么单例可能是邪恶的
  • @Whisher:我用有关objects are passed by reference to a method 的信息更新了我的答案。希望对你来说更清楚。
  • @Whisher:你有什么不清楚的地方?在更新 3 中,您使用 Animal 函数创建了一个 new object,并使用新的 ngDogngCat 扩展了该对象。 Animal 是一个函数,没有任何修改。
  • 在更新 2 中,服务是单例的,狗重写猫的设置。 Cat 具有与 Dog 相同的道具/方法。
  • @Whisher:在更新 2 中,您的 AnimalDogCat 指的是同一个对象。
【解决方案2】:

您的示例使用factory,而不是service。请注意,provider 也是游戏的一部分。

迄今为止最好的学习资源:

AngularJS: Service vs provider vs factory

Miško Hevery 给出了一个启发性的解释,以及factoryserviceprovider 的实际示例。 强烈推荐

【讨论】:

  • 我在一个用户案例中使用了工厂,但是 angularjs 引用将服务作为一个整体来引用(工厂、服务、提供者)
  • 工厂/服务区分与它无关。 “工厂”和“服务”模式都是构建服务的不同方式。 所有服务都是“单例”,无论它们是如何构建的。 @Whisher 的原始示例的问题是构造 Animal 服务的函数不返回对象 - 它返回另一个函数。所以 Animal 的“服务”实际上是一个函数——仍然是一个“单例”,而不是一个对象。然后使用 Animal “singleton” 函数来构造 Dog 和 Cat 服务,在这种情况下它们是对象。 (哇!)
【解决方案3】:

是的,服务是单例的。以下代码仅将一个“M”记录到控制台:

function M() { console.log('M'); }
function M1(m) { console.log(1); }
function M2(m) { console.log(2); }
angular.module('app', [])
.service('M', M)
.service('M1', ['M', M1])
.service('M2', ['M', M2])
.controller('MainCtrl',function(M1, M2){});

run it in jsbin

【讨论】:

    【解决方案4】:

    让我举一个关于 AngularJS 中的单例的例子。 假设我们在单页应用程序的不同部分使用了 2 个控制器:

    myApp.controller('mainController', ['$scope', '$log', function($scope, $log) {
    
        $log.main = 'First Var';
        $log.log($log);
    
    }]);
    

    所以现在如果我们转到通过mainController 控制器控制的页面,我们将在日志中看到:

    如您所见,日志对象现在包含我的第一个变量。

    现在这是我的第二个控制器:

    myApp.controller('secondController', ['$scope', '$log', '$routeParams', function($scope, $log, $routeParams) {
    
        $log.secondVar = 'Second Var';
        $log.log($log);
    
    }]);
    

    所以如果你点击被控制的第二个页面,你会看到:

    现在回到第一页:

    您对这 3 个步骤有何看法?

    它们是注入到应用程序中的一个$log 对象。正如 Tony Alicea 所说:这是一个很大的内存节省。

    所以这个服务,被调用一次,每次我们都在为同一个对象添加新的变量和参数,而不是为不同的参数添加不同的对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-13
      • 2013-03-13
      • 2014-12-30
      • 2011-01-11
      • 2020-01-15
      • 2016-12-30
      • 2017-01-25
      • 1970-01-01
      相关资源
      最近更新 更多