在 $rootScope 中存储变量是好的做法吗?
Is storing variables in $rootScope good practice?
更新 2:我找到了解决方案
我已将设置文件更改为一个 JS 文件,将 var tempSettings =
添加到文件的开头,并将其添加到 index.html 中。这样它就加载了初始的 HTML,确保它在 app.run 消失时存在。设置服务然后获取此 tempSettings
变量并将其放入服务中。为了清理,我删除了 tempSettings 指针。
名为 settings.js
的新设置文件
var tempSettings = {
"environment": "development",
[...]
添加到 index.html:
<script src="settings.js"></script>
服务:
myApp.service("settings", function(){
var settings = null;
this.initialize = function() {
settings = tempSettings;
tempSettings = undefined;
};
this.get = function() {
return settings;
}
});
更新一:我发现了一个问题
因为设置文件是异步加载的,所以有时模块会在加载之前尝试使用这些设置。我会及时通知您最新的解决方案。我已经把设置移到服务里了,那肯定更好。
原问题
当我 google 如何在 AngularJS 应用程序中存储环境设置时,我遇到了使用 Grunt 或 Gulp 的选项(可能还有其他选项),但对我来说选项似乎更明显。这意味着可能有充分的理由不使用它。这种存储设置的方式是个坏主意吗?
我的应用程序根目录中有一个名为 settings.json 的文件,它看起来像这样:
{
"settingsFile": true,
"environment": "development",
"logLevel": "debug",
"userApiBase": "http://localhost/covlelogin/web/api/",
"oAuth": {
"google":{
"endpoint": "https://accounts.google.com/o/oauth2/auth",
"clientId": "12345",
"scope": "email profile",
"state": "MyToken123",
"redirectUri": "http://localhost/loginadmin/web/oAuthRedirect",
"responseType": "code",
"approvalPrompt": "force"
}
}
}
然后我在 app.run 中有一点看起来像这样:
MyApp.run(function ($rootScope, $http) {
//Load settings
$http.get('settings.json').
success(function (settings) {
if (settings.settingsFile){
$rootScope.settings = settings;
console.log("Settings loaded");
}else{
console.log("Error loading settings. File may be corrupt.");
//Additional error handling
}
}).
error(function (data) {
console.log("Error getting settings file.");
//Additional error handling
})
});
现在每当我需要设置时,我总是可以转到 $rootScope.settings.userApiBase
或其他任何地方。这对我来说很有意义,因为我所要做的就是确保 settings.json 在签入时被忽略。整个方法非常简单。这个设计有缺陷吗?
一般来说,您应该尽可能避免污染 rootScope。我喜欢您在 app.run() 中加载设置。引入一个在 app.run 中填充并可以注入到您的其他 controllers/services 中的 SettingsService 怎么样?这具有在单元测试期间可模拟的附加值。
这是一个plunker
app.run(function(SettingsService) {
SettingsService.name = "Alex";
SettingsService.password = "pw1";
})
app.controller('MainCtrl', function($scope, SettingsService) {
$scope.settings = SettingsService;
});
app.factory('SettingsService', function() {
return {}
})
尽量不要污染$rootScope
Here。创建一个设置服务来处理设置。服务是单例对象,因此一旦您 initialize
服务,设置将在您注入服务的任何地方可用。
MyApp.service("Settings", function($http) {
var settings = null;
this.initialize = function() {
$http.get('settings.json').success(function (s) {
if (s.settingsFile){
settings = s;
console.log("Settings loaded");
} else {
console.log("Error loading settings. File may be corrupt.");
//Additional error handling
}
}).error(function (data) {
console.log("Error getting settings file.");
//Additional error handling
})
};
this.get = function() {
return settings;
}
return this;
});
在MyApp.run
中:
MyApp.run(function (Settings) {
Settings.initialize();
}
然后,每当您想在控制器或其他服务或其他东西中访问 Settings
时,只需调用 Settings.get()
即可 return 您的设置。只要确保将 Settings
服务注入到任何使用它的东西中(就像我在第二个代码块中所做的那样)。
更新 2:我找到了解决方案
我已将设置文件更改为一个 JS 文件,将 var tempSettings =
添加到文件的开头,并将其添加到 index.html 中。这样它就加载了初始的 HTML,确保它在 app.run 消失时存在。设置服务然后获取此 tempSettings
变量并将其放入服务中。为了清理,我删除了 tempSettings 指针。
名为 settings.js
var tempSettings = {
"environment": "development",
[...]
添加到 index.html:
<script src="settings.js"></script>
服务:
myApp.service("settings", function(){
var settings = null;
this.initialize = function() {
settings = tempSettings;
tempSettings = undefined;
};
this.get = function() {
return settings;
}
});
更新一:我发现了一个问题
因为设置文件是异步加载的,所以有时模块会在加载之前尝试使用这些设置。我会及时通知您最新的解决方案。我已经把设置移到服务里了,那肯定更好。
原问题
当我 google 如何在 AngularJS 应用程序中存储环境设置时,我遇到了使用 Grunt 或 Gulp 的选项(可能还有其他选项),但对我来说选项似乎更明显。这意味着可能有充分的理由不使用它。这种存储设置的方式是个坏主意吗?
我的应用程序根目录中有一个名为 settings.json 的文件,它看起来像这样:
{
"settingsFile": true,
"environment": "development",
"logLevel": "debug",
"userApiBase": "http://localhost/covlelogin/web/api/",
"oAuth": {
"google":{
"endpoint": "https://accounts.google.com/o/oauth2/auth",
"clientId": "12345",
"scope": "email profile",
"state": "MyToken123",
"redirectUri": "http://localhost/loginadmin/web/oAuthRedirect",
"responseType": "code",
"approvalPrompt": "force"
}
}
}
然后我在 app.run 中有一点看起来像这样:
MyApp.run(function ($rootScope, $http) {
//Load settings
$http.get('settings.json').
success(function (settings) {
if (settings.settingsFile){
$rootScope.settings = settings;
console.log("Settings loaded");
}else{
console.log("Error loading settings. File may be corrupt.");
//Additional error handling
}
}).
error(function (data) {
console.log("Error getting settings file.");
//Additional error handling
})
});
现在每当我需要设置时,我总是可以转到 $rootScope.settings.userApiBase
或其他任何地方。这对我来说很有意义,因为我所要做的就是确保 settings.json 在签入时被忽略。整个方法非常简单。这个设计有缺陷吗?
一般来说,您应该尽可能避免污染 rootScope。我喜欢您在 app.run() 中加载设置。引入一个在 app.run 中填充并可以注入到您的其他 controllers/services 中的 SettingsService 怎么样?这具有在单元测试期间可模拟的附加值。
这是一个plunker
app.run(function(SettingsService) {
SettingsService.name = "Alex";
SettingsService.password = "pw1";
})
app.controller('MainCtrl', function($scope, SettingsService) {
$scope.settings = SettingsService;
});
app.factory('SettingsService', function() {
return {}
})
尽量不要污染$rootScope
Here。创建一个设置服务来处理设置。服务是单例对象,因此一旦您 initialize
服务,设置将在您注入服务的任何地方可用。
MyApp.service("Settings", function($http) {
var settings = null;
this.initialize = function() {
$http.get('settings.json').success(function (s) {
if (s.settingsFile){
settings = s;
console.log("Settings loaded");
} else {
console.log("Error loading settings. File may be corrupt.");
//Additional error handling
}
}).error(function (data) {
console.log("Error getting settings file.");
//Additional error handling
})
};
this.get = function() {
return settings;
}
return this;
});
在MyApp.run
中:
MyApp.run(function (Settings) {
Settings.initialize();
}
然后,每当您想在控制器或其他服务或其他东西中访问 Settings
时,只需调用 Settings.get()
即可 return 您的设置。只要确保将 Settings
服务注入到任何使用它的东西中(就像我在第二个代码块中所做的那样)。