0

我在我的项目中使用 angular 和 grafana。我有一个service->dashboardViewStateSrv

我的服务代码:

define([
  'angular',
  'lodash',
  'jquery',
],
function (angular, _, $) {
  'use strict';

  var module = angular.module('grafana.services');

  module.factory('dashboardViewStateSrv', function($location, $timeout) {

    function DashboardViewState($scope) {
      var self = this;
      self.state = {};
      self.panelScopes = [];
      self.$scope = $scope;
     // something
    }

    return {
      create: function($scope) {
        return new DashboardViewState($scope);
      }
    };

  });
});

在我的侧面菜单控制器中:

 $scope.dashboardViewState = dashboardViewStateSrv.create($scope);

    if ($scope.dashboardViewState) {
       if($scope.dashboardViewState.state.citreedepth){
          depth = +$scope.dashboardViewState.state.citreedepth;
       }
    }

在我的仪表板控制器中:

$scope.dashboardViewState = dashboardViewStateSrv.create($scope);

DashboardViewState对象被创建两次(Dashboard Ctrl 和 Side Menu ctrl)。我创建了DashboardViewState两次对象,我想避免这种情况。如果我可以避免DashboardViewState在侧边菜单 ctrl 中创建对象?

应该只有一种视图状态。据我了解,所有服务都是有角度的。

请指导我能做什么?

4

1 回答 1

1

服务是单例的,它们本质上是一个构造函数,允许您在this其中使用关键字。它们在首次创建时被实例化一次,然后该实例在整个应用程序中共享。

工厂就是工厂。在 Angular 的某个地方,它会调用Object.create()你从工厂返回的对象。这意味着每次调用都将返回它的一个新实例。

因此,在您的用例中,您创建了两次新对象。首先使用工厂,然后从该工厂返回一个新对象。

这可能会有所帮助http://blog.thoughtram.io/angular/2015/07/07/service-vs-factory-once-and-for-all.html

因此,如果您希望通过您的应用程序获得一个对象的单个实例,您应该使用.service()not .factory()

如果您只想在可以使用服务时实例化一个新对象。将对象作为属性和 get 方法。该服务可以检查对象是否已经创建,如果没有创建。

像这样的东西(示例代码,未经测试):

  module.service('dashboardViewStateSrv', function($location, $timeout) {

    this.object;

    this.get = function (){
        if(this.object === undefined) {
            return this.object = Object.create({}); //Create your object
        } else {
            return this.object;
        }
    }
});

但是我确实注意到了一些嘘声(抱歉,当我这么说时,我总是想起 Hook)。首先,您不需要为this关键字起别名,不在 jQuery 回调中工作,即使我们是您可以绑定您的函数等。

其次,这很重要。您将$scope对象传递给您的服务,这是非常非常糟糕的。不只是因为这个原因,如果一个服务对象引用了 a ,控制器如何共享一个服务对象$scope?您的服务应该是具有输入和输出数据的单个简单方法的集合。他们致力于此并继续。然后,您可以链接它们并将每个方法所需的特定数据传递给它们。它们不应该是一个具有隐藏属性的整体对象,如果你愿意,可以考虑功能,一个管道。

于 2015-10-20T06:49:27.477 回答