在使用模块时,如何扩展或隔离AngularJS中的常量值?
为了保持代码整洁,我习惯在AngularJs应用程序中将url定义为常量,如下所示:在使用模块时,如何扩展或隔离AngularJS中的常量值?,angularjs,constants,modularity,Angularjs,Constants,Modularity,为了保持代码整洁,我习惯在AngularJs应用程序中将url定义为常量,如下所示: var myApp = angular.module('myApp', ['myModule']); myApp.constant('URL', { google: 'http://www.google.com', facebook: 'http://www.facebook.com' }); 现在,这很好,但当我在模块中定义(并使用)这个常量时,我遇到了问题: var myModule= a
var myApp = angular.module('myApp', ['myModule']);
myApp.constant('URL', {
google: 'http://www.google.com',
facebook: 'http://www.facebook.com'
});
现在,这很好,但当我在模块中定义(并使用)这个常量时,我遇到了问题:
var myModule= angular.module('myModule', []);
myModule.constant('URL', {
twitter: 'http://www.twitter.com'
});
因为,现在当我想在指令(在我的模块内)中使用URL.twitter常量时,它不再可用,因为“myApp”中URL常量的定义已经覆盖了该值。例如,当我创建指令时:
myModule.directive('myDirective', function(){
return {
template: '<div></div>',
controller: function(URL){
console.log(URL.twitter); // logs undefined when used within 'myApp'
}
};
});
myModule.directive('myDirective',function(){
返回{
模板:“”,
控制器:函数(URL){
console.log(URL.twitter);//在“myApp”中使用时未定义日志
}
};
});
请参见一个实例:
把“myModule”想象成我在项目中包含的第三方模块。如果我不小心对常量使用了相同的名称,那么整个过程都会被破坏
如何克服此用例而不必为同一目的使用不同的名称?您正在创建一个名为myApp的角度模块,它取决于模块myModule
然后向模块myApp
var myApp = angular.module('myApp', ['myModule']);
myApp.constant('URL', {
google: 'http://www.google.com',
facebook: 'http://www.facebook.com'
});
然后创建myModule,并将twitter常量添加到其中。即:-谷歌和facebook都将绑定到myApp
-twitter绑定到myModule 然后,将URL注入到指令中,尝试恢复twitter URL。 这在很大程度上取决于
myModule.directive
行之前的内容
使用:var myModule=angular.module('myModule')
您应该找到twitter常量使用:
var myModule=angular.module('myApp')
您应该找到google和facebook常量
我通常使用一种更清晰的方法(在我看来):
var myApp = angular.module('myApp')
myApp.factory('appConstants', function() {
return {
facebook: "www.facebook.com",
google: "www.google.com",
twitter: "www.twitter.com"
}
})
然后你只要在需要的时候注入它,像这样使用:appConstants.facebook
你觉得怎么样?我想问题可以归结为: 第三方模块(我没有编写)将“URL”定义为常量 我将此模块作为依赖项包含在我的应用程序中,并定义URL(不知道URL已经定义): 突然,应用程序中断并停止工作 如何避免这个陷阱 答复: 您可以使用angular的喷油器确定是否已定义常数:
var app = angular.module('myApp', ['thirdPartyModule']);
app.constant('URL', { twitter: 'www.twitter.com'});
angular.module('myApp', ['thirdPartyModule']);
var injector = angular.injector(),
url = injector.has('URL') ? injector.get('URL') : {};
上面的代码将保证返回一个对象——或者是在第三方模块中定义的URL,或者是一个空的对象文本(如果没有定义)
然后,您可以按如下方式扩展“URL”:
angular.extend(url, { twitter: 'www.twitter.com' });
警告:
如果URL以前未定义或在第三方模块中定义为对象文本,则此操作将起作用。如果URL以前定义为原语(即字符串),则此操作将不起作用
不幸的是,我想不出一个干净的方法来防范这种情况。我建议不要覆盖以前定义的常量,并依靠命名约定使您的可注入项唯一。例如,对于常量、服务、提供程序和工厂,请使用唯一的前缀,以减少命名冲突的可能性:
var app = angular.module('tgApp', ['thirdPartyModule']);
app.constant('tgURL', { ... });
我意识到这是一个老问题,但我没有看到这个答案。我只是花了几个小时把头撞在桌子上,讨论的正是OP描述的同一个问题。我有很多jQuery小部件要转换成angular。这些基本上是第三方模块,将在多个站点上使用。我通过为每个模块使用一个提供者解决了这个问题
var myModule = angular.module('myModule', []);
myModule.provider('myModuleProvider', function() {
this.$get = [function() {
return {
twitter: 'http://www.twitter.com',
};
}]
})
myModule.directive('myDirective', function() {
return {
template: '<div></div>',
controller: function(myModuleProvider) {
var URL = myModuleProvider;
console.log(URL.twitter);
}
}
})
var myModule=angular.module('myModule',[]);
provider('myModuleProvider',function(){
这个。$get=[function(){
返回{
推特:'http://www.twitter.com',
};
}]
})
myModule.directive('myDirective',function(){
返回{
模板:“”,
控制器:功能(myModuleProvider){
var URL=myModuleProvider;
log(URL.twitter);
}
}
})
我的示例确实充分利用了提供者,但好处是它们可以配置。因此,如果我有要公开的“选项”,可以通过myModule注入到的模块上的angular.config()函数对其进行配置。我读了5遍,但仍然无法理解您的问题。。。你能换个说法吗?@domokun现在说得通了吗?我添加了一个例子。考虑过创建一个URL服务并在需要的地方注入吗?我仍然有点困惑,但我想我已经发现了几个问题。给我5分钟,我添加了一个plunker示例。谢谢你的回答,但这并不能解决问题。下面是修改后的plunker:。如您所见,它仍然覆盖这些值。整个问题是,我希望常数具有相同的值,在模块内被隔离。作为旁注,我认为我们应该使用angular提供的.constants选项。假设myModule是我在项目中包含的第三方模块。如果我不小心在常量中使用了相同的名称,那么整个过程都会被破坏。您只是更改了名称,但您引用的模块是错误的!如果您尝试打印(在Plunkr中)
constants.google
,则您正在创建两个不同的实体,并尝试使用一个不可见的实体。在“myApp”中创建的模块与我知道的“myModule”中的模块是隔离的…但我不尝试从myModule中的myApp访问常量。我只是试图从“myModule”中的“myModule”访问常量(twitter),但只有我在使用“myApp”中的指令:)这就是我要找的。我已经想到了一个扩展解决方案,但无法找到一个(干净的)方法来实现它。在我看来,喷油器溶液也不是“干净的”,但……它是一种溶液。我不能