为了保持我的代码清洁,我习惯在我的AngularJs应用程序中将url定义为常量,看起来像:
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'
}
};
});
查看实时示例:http://plnkr.co/edit/xiOGVWfJ4GupSvkTs0Ic?p=preview
将'myModule'视为我在项目中包含的第三方模块。如果我不小心为常量使用相同的名称,那么整个事情就会被打破。
如何克服此用例而不必为同一目的使用不同的名称?
答案 0 :(得分:4)
我认为这个问题归结为:
第三方模块(我没有写过)定义了&#39; URL&#39;作为常数。
我将此模块作为依赖项包含在我的应用中,并定义了URL(不知道该URL已经定义):
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或空对象文字。
然后,您可以扩展&#39; URL&#39;如下:
angular.extend(url, { twitter: 'www.twitter.com' });
谨慎之词:
如果以前未定义URL或在第三方模块中将URL定义为对象文字,则此方法可行。如果先前将URL定义为基元(即字符串),则无效。
不幸的是,我无法想办法以干净的方式防范这种情况。我建议不要重写先前定义的常量,并依靠命名约定来使您的注射剂具有唯一性。例如,对于常量,服务,提供者和工厂,使用唯一的前缀来减少命名冲突的可能性:
var app = angular.module('tgApp', ['thirdPartyModule']);
app.constant('tgURL', { ... });
答案 1 :(得分:1)
我意识到这是一个老问题,但我没有看到这个答案。在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);
}
}
})
我的示例确实充分利用了提供程序,但好处是它们可以配置。因此,如果我有“选项”,我想公开它们可以通过myModule注入的模块上的angular.config()函数进行配置。
答案 2 :(得分:0)
您正在创建名为 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
你怎么看?