Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在使用模块时,如何扩展或隔离AngularJS中的常量值?_Angularjs_Constants_Modularity - Fatal编程技术网

在使用模块时,如何扩展或隔离AngularJS中的常量值?

在使用模块时,如何扩展或隔离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

为了保持代码整洁,我习惯在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'
        }
    };
});
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')
您应该找到googlefacebook常量


我通常使用一种更清晰的方法(在我看来):

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”中的指令:)这就是我要找的。我已经想到了一个扩展解决方案,但无法找到一个(干净的)方法来实现它。在我看来,喷油器溶液也不是“干净的”,但……它是一种溶液。我不能