对于我客户的网站,我使用版本 1.5.7 的 Angular JS。在这个网站上还有一个动态机制来集成远程JS应用程序。该机制首先加载一个配置文件,其中包含必须加载其他脚本和样式表的信息。加载的应用程序之一也使用 Angular JS,但版本为 1.3.9。此星座会导致错误,表明版本与 ngAnimate 模块不兼容。
我的第一个解决方案是将window.angular
移动到window.vendor.angular
并删除window.angular
,以便远程加载Angular JS可以正常工作。此解决方案的问题在于,Angular JS 在多个位置使用 $window.angular。
替换 window.angular
和 $window.angular
并不是真正的解决方案,因为我想从公共(public) CDN 加载 AngularJS。
我现在正在寻找一种解决方案,可以完全隔离地运行 Angular JS 或类似 jQuery 的 jQuery.noConflict()
。
最佳答案
这是一个非常简单的解决方案,不是那么花哨,但它有效。当 AngularJS 代码加载时,它会存储一个内部变量来存储 AngularJS API。因此,解决方案是加载 angularjs 1.5.7
并将其存储在单独的位置(即 window.angular1_5_7
)并清除之前的声明(即 window.angular = {};
),因此当 1.3.9
加载时,不会出现任何冲突。
<script>
// angularjs stores window.angular internally when it is declared
// var angular = window.angular || (window.angular = {}),
window.angular1_5_7 = window.angular;
window.angular = {};
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
然后1.3.9
将在正常流程上引导。您也可以使用 ng-app
。
(function() {
angular.module('app139', []);
angular.element(document).ready(function() {
var element = angular.element(document.getElementById('app139'));
angular.bootstrap(element, ['app139']);
});
})();
最后,当您引导 1.5.7
应用程序时,您可以指定 Angular 1.5.7
的存储版本(即 window.angular1_5_7
)。
(function(angular) {
angular.module('app157', []);
angular.element(document).ready(function() {
var element = angular.element(document.getElementById('app157'));
angular.bootstrap(element, ['app157']);
});
})(window.angular1_5_7);
$window.Angular 和代理
这似乎不是问题,因为使用 $window.angular
时 angularjs 不会导致冲突,但如果是这样,您可以尝试此解决方案。
我能找到解决 $window.angular
问题的唯一方法是使用 ES6 proxies中间属性 'angular'
的 get
,将其解析为 $window
服务的装饰器。因此,当 $window
对名为 angular
的属性执行 get
时,它将返回 window.angular1_5_7
否则将返回普通对象。
Unfortunately, it's not fully compatible with all browser yet, it has been introduced on ES6 and there is no equivalent implementation on ES5.
angular.module('app157', [])
.config(function($provide) {
$provide.decorator('$window', function $windowDecorator($delegate) {
return new Proxy($delegate, {
get: function(target, prop) {
return prop == 'angular' ?
window.angular1_5_7 :
target[prop]
}
});
});
})
完整的工作片段:
// app 1.3.9 declarations
(function() {
angular.module('app139', [])
.run(function($rootScope, $window) {
$rootScope.version = $window.angular.version;
});
angular.element(document).ready(function() {
var element = angular.element(document.getElementById('app139'));
angular.bootstrap(element, ['app139']);
});
})();
// app 1.5.7 declarations
(function(angular) {
angular.module('app157', [])
.config(function($provide) {
$provide.decorator('$window', function $windowDecorator($delegate) {
return new Proxy($delegate, {
get: function(target, prop) {
return prop == 'angular' ?
window.angular1_5_7 :
target[prop]
}
});
});
})
.run(function($rootScope, $window) {
$rootScope.version = $window.angular.version;
});
angular.element(document).ready(function() {
var element = angular.element(document.getElementById('app157'));
angular.bootstrap(element, ['app157']);
});
})(window.angular1_5_7);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.js"></script>
<script>
// angularjs stores window.angular internally when it is declared
// var angular = window.angular || (window.angular = {}),
window.angular1_5_7 = window.angular;
window.angular = {};
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.js"></script>
<div id="app139">
<h2>app 1.3.9</h2>
<p>{{ version }}</p>
</div>
<div id="app157">
<h2>app 1.5.7</h2>
<p>{{ version }}</p>
</div>
关于javascript - 在自定义命名空间上使用 AngularJs 并删除 window.angular,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40527045/