为什么在我的require.js配置中没有调用`init`的shim? [英] Why `init` of shim in my require.js configuration not called?

查看:78
本文介绍了为什么在我的require.js配置中没有调用`init`的shim?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新

我正在编写一个小模块来处理 backbone 中的csrf令牌问题,直到我得到了@Louis答案的推送通知。

I was writing a small module to handle this csrf token problem in backbone until I got push notification of @Louis's answer.

他的答案很优雅,看起来不错,但我会离开链接到我的 backbone.csrf 模块github repo,仅供有需要的人使用。

His answer is quite elegant and seems nice, but I'll leave a link to my backbone.csrf module github repo just for anyone who needs it.

============================================= =======================

====================================================================

我正在使用 Backbone 作为我的前端框架以及我的 Django 后端。

I'm using Backbone as my frontend framework along with my Django backend.

我必须配置我的 Backbone.sync 在发送之前为每个AJAX请求设置CSRF请求标头,以便与Django的CSRF保护系统兼容。

I had to configure my Backbone.sync to set CSRF request header for every single AJAX requests before it sends it, for compatibility with Django's CSRF protection system.

因为我使用的是 require。 js 对于模块化的javascript开发,我试图在 shim.init 中配置 requir e.config 以便在浏览器上加载Backbone后立即触发此重写:

Since I was using require.js for modular javascript development, I tried to configure this in shim.init of require.config so that this overriding will be fired as soon as the Backbone is loaded on browser:

<script>
    var require = {
        ...

        shim: {
            'jquery': {'exports': 'jQuery'},
            'backbone': {
                'deps': ['underscore', 'jquery'],
                'exports': 'Backbone',
                'init': function(_, $) {
                     alert('NOT EVEN CALLED');
                     var originalSync = this.Backbone.sync;
                     this.Backbone.sync = function(method, model, options) {
                         options.beforeSend = function(xhr) {
                             xhr.setRequestHeader('X-CSRFToken', window.csrf_token);
                         }
                         return originalSync(method, model, options);
                     }
                 }
            }
        }
    }
</script>
// Load require.js
<script src="require.js"></script>

虽然Backbone已成功加载,但是不会调用require配置的'init' 。

Although the Backbone has been successfully loaded, the 'init' of the require configuration doesn't get called.

有什么问题?

推荐答案

看着< a href =http://backbonejs.org/docs/backbone.html\"rel =noreferrer>带注释的源,我看到Backbone调用 define 当它检测到它正在运行AMD加载程序时。使用带有 define 的模块的 shim 会导致未定义的行为,因为 shim 适用于不调用 define 的模块。

Looking at the annotated source, I see that Backbone calls define when it detects it is running with an AMD loader. Using a shim with a module that calls define results in undefined behavior because shim is for modules that do not call define.

您可以使用假的主干模块实现您想要的功能,您可以将其保存在名为的文件中 backbone-glue.js

You could achieve what you want with a fake backbone module like this which you'd save in a file named backbone-glue.js:

define(['backbone'], function (Backbone) {
    var originalSync = Backbone.sync;
    Backbone.sync = function(method, model, options) {
        options.beforeSend = function(xhr) {
            xhr.setRequestHeader('X-CSRFToken', window.csrf_token);
        }
        return originalSync(method, model, options);
    };

    return Backbone;
});

然后你的RequireJS配置应该有这样的地图:

And then you should have a map like this in your configuration for RequireJS:

map: {
     '*': {
          backbone: 'backbone-glue'
     },
     'backbone-glue': {
          backbone: 'backbone'
     }
}

当需要模块 backbone 时,它的作用是什么( * )RequireJS loading backbone-glue 代替。但是,在 backbone-glue 中,当需要 backbone 时,则 backbone 已加载。这允许 backbone-glue 加载原始Backbone。

What this does is that everywhere (*) when the module backbone is required RequireJS loads backbone-glue instead. However, in backbone-glue, when backbone is required, then backbone is loaded. This allows backbone-glue to load the original Backbone.

这篇关于为什么在我的require.js配置中没有调用`init`的shim?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆