为什么在我的require.js配置中没有调用`init`的shim? [英] Why `init` of shim in my require.js configuration not called?
问题描述
更新:
我正在编写一个小模块来处理 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屋!