我在项目中使用角度和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
对象?
应该只有一个视图状态。根据我的理解,所有服务都是角度单身。
请指导我能做些什么?
答案 0 :(得分:1)
服务是单件,它们本质上是一种结构函数,允许您在其中使用this
关键字。它们在首次创建时实例化,然后在整个应用程序中共享该实例。
工厂就是工厂。在Angular的某个地方,它会在你从工厂返回的对象上调用Object.create()
。这意味着每次调用都会返回一个新的实例。
因此,在您的用例中,您需要两次创建一个新对象。首先使用工厂,然后从工厂返回一个新对象。
这可能有助于http://blog.thoughtram.io/angular/2015/07/07/service-vs-factory-once-and-for-all.html
因此,如果您希望通过应用程序获得对象的单个实例,则应使用.service()
而不是.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;
}
}
});
然而,我确实注意到了一些booboo(对不起,当我这么说时,总是让我想起Hook)。首先,您不需要为this
关键字设置别名,也不需要在jQuery回调中工作,即使我们您可以绑定您的函数等。
第二,这很重要。您将$scope
对象传递给您的服务,这非常非常糟糕。不仅仅是因为这个原因,但如果控制器引用$scope
,它们如何共享一个服务对象?您的服务应该是具有输入和输出数据的单个简单方法的集合。他们继续努力并继续努力。然后,您可以链接它们并将每个方法所需的特定数据传递给它们。它们不应该是一个单一的对象,它具有隐藏属性中的所有东西,想象功能,如果你愿意的话就是一个管道。