将jQuery名称空间注入AngularJS

时间:2015-11-24 17:09:49

标签: javascript jquery angularjs requirejs

我在这里遇到了一些麻烦。

我正在使用RequireJS来加载我的模块和依赖项。 我试图避免污染全局命名空间,所以我使用以下配置作为起点,以避免在全局窗口对象中定义$jQuery

require.config({
    map: {
       '*': { 'jquery': 'jquery-no-conflict' },
       'jquery-no-conflict': { 'jquery': 'jquery' }
    },
    shim: {
       'jquery': { exports: 'jQuery' },
       'angular': { exports: 'angular', deps: ['jquery'] }
       // ...
    }
});

模块jquery-no-conflict看起来像这样:

define('jquery-no-conflict', ['jquery'], function (jQuery) {
    return jQuery.noConflict(true);
});

这显然解决了这个问题,但是存在问题。

我不知道有一些不同的AngularJS行为,不管是否加载了jQuery,显然,这是通过检查全局命名空间来完成的。

例如,如果没有找到或加载jQuery,AngularJS $window将是本机元素window的包装,但如果定义了jQuery,它将是jQuery的$(window)的包装器

对于我网站上的某些功能,我需要后者,但是通过这种配置,我得到了前者(因为AngularJS似乎没有找到jQuery);

有没有办法将我的jQuery模块/变量注入AngularJS并让它不检查全局命名空间?

如您所见,我的jquery模块正在导出,因此RequireJS会在请求时给我一个范围变量。

如果无法做到这一点,你会在我的情况下做些什么?可以做些什么来解决这个问题?

2 个答案:

答案 0 :(得分:0)

如果传统的jQuery全局变量导致问题,可以使用ng-jq attrubute为jQuery提供自定义window属性。

截至今天,Angular仍然依赖于全局变量jQuery isn't an exception

答案 1 :(得分:0)

加载jQuery后,您可以从requirejs手动bootstrap应用程序并在服务中提供它。

requirejs(['jquery'], function (jQuery) {
    angular.module('HelloApp').
    service('jQuery', function () {
        return jQuery.noConflict();
    });
    angular.bootstrap(document, ['HelloApp']);
});

请注意,您不会在html标记中包含ng-app

requirejs.config({
    "baseUrl": "js/lib",
        "paths": {
        "jquery": "//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min",
    }
});

angular.module('HelloApp', []).
controller('HelloController', [function (jQuery) {
    var HelloController = this;
    HelloController.greet = function () {
        return "Hello from HelloController!";
    }

}]).
directive('anoyatron', ['jQuery',function (jQuery) {
    return {
        restrict: 'A',
        link: function (scope, element) {
            function anoyatron(){
             	jQuery(element).slideUp(function(){jQuery(element).slideDown(anoyatron);});   
            }
            anoyatron();
        }
    };
}]);
requirejs(['jquery'], function (jQuery) {
    angular.module('HelloApp').
    service('jQuery', function () {
        return jQuery.noConflict();
    });
    angular.bootstrap(document, ['HelloApp']);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.22/require.min.js"></script>
<div ng-controller="HelloController as HelloController">
    <p>{{HelloController.greet()}}</p>
</div>
<div anoyatron>lorem ipsum</div>