问题描述
|
有没有在RequireJS模块中传递服务器数据的首选方法?我们当前的实现类似于以下代码片段;使用\'page \'对象保存所有服务器/动态数据,并将其传递给主引导程序。 (我们目前不希望使用ajax来填充任何依赖项)
从服务器页面:
<script data-main=\"scripts/main\" src=\"scripts/require-jquery.js\"></script>
<script type=\"text/javascript\">
define(\"page\",function () {
return { guid: \"<%=Guid.NewGuid() %>\" };
});
</script>
main.js
require([\"jquery\",\"jquery.alpha\",\"page\"],function ($,alpha,page) {
alpha.initialize(page);
});
jquery.apha.js
define([\"jquery\",page) {
return {
initialize: function () {
console.log(page.guid);
//logs guid as expected
}
}
});
解决方法
RequireJS关于如何处理服务器数据一无所获,因为它是模块化JavaScript的一种方式。因此,在这方面,没有事实上的标准,您可以根据需要将RequireJS与json,ajax,php,嵌入式xml等结合使用。
两种方法
通常有两种方法可以解决此问题。
建模从服务器获取所需数据的\'dao \'或\'service \'模块
使用户可以访问它(类似于您当前的方法,请参见下面的代码示例)
定义所有模块均可访问的全局对象
第一种方法将参数添加到您的函数。
第二个提供全局访问。这也需要您自己的初始化代码才能开始获取数据。
这取决于个人喜好以及您拥有多少个“道”。如果您有多个,则可能会污染,因为每个dao模块都需要一个新参数。在这种情况下,使它们具有全球性似乎更清洁。
您的方法有问题
但是,当前的方法存在一个问题,您将Page模块作为定义(使用
define()
而不是require()
),因为为依赖于它的每个对象都创建了一个定义模块。这可能意味着在同一页面中有多个呼叫。而是使用:
// in seperate file page.js:
require([],function () {
return { guid: \"<%=Guid.NewGuid() %>\" };
});
通过这种方式,RequireJS将页面识别为模块,因为它是一个单独的文件,并且每页仅会进入您的服务器一次。
,我通常会执行以下操作(在后端使用PHP,但任何方法都可以):
<script src=\"scripts/require-jquery.js\"></script>
<script>
require([\'scripts/main\'],function(App) {
var myApp = new App({
param1: <?=json_encode($param1);?>,param2: <?=json_encode($param2);?>
});
});
</script>
然后将我的模块定义为需要配置的内容:
define([\'jquery\'],function($) {
var App = function(options) {
this.options = options;
//blabla
}
// add some stuff to App.prototype maybe
// and finally...
return App;
});
,如果您有JSON对象,请像注释中提到的@yves一样进行AJAX调用。
如果您不想这样做,还有其他选择。您可以将guid作为数据属性放在脚本标签上。另外,您可以尝试使loader js文件动态化,以便在其中进行配置。
坦白说,我只是打一个AJAX电话。
,使用window全局变量将服务器数据传输到js应用程序中:
<script type=\"text/javascript\">
window.server_data=parseJSON(<?php echo json_encode(array (\"server_data\"=>\"it works!\"));?>);
</script>
<script data-main=\"js/application\" src=\"js/lib/require.js\"></script>
在application.js中:
requirejs([\"app/main\"],function (MyApp){
console.dir(window.server_data); //all our application need this global variable
var myApp=new MyApp();
myApp.init(window.server_data); //and your application now has server data
});
,我今天刚从RequireJS
开始,在此之前,我曾经被用来调用要在页面加载时执行的函数,如下所示:
<script>
my_method(<?php echo json_encode( array(\'opt1\'=>true,\'opt2\'=>false) );?>);
</script>
正如@ ziad-saab一样,我发现我能做的最相似的事情不是使用data-main
属性,而是定义一个内联模块:
<script src=\"path/to/require.js\"></script>
<script>
require([\'my/module\'],function(module){
module.my_method(<?php echo json_encode( array(\'opt1\'=>true,\'opt2\'=>false) );?>);
});
</script>
data-main
属性指示RequireJS
在require.js和所有模块依赖项加载后立即执行模块。忽略它(模块),然后将其定义为内联模块,我可以抛出PHP
变量。
这样,我就不需要处理保存配置的模块,在我的环境中,使用requirejs的过渡也更容易。
,我发现一些答案令人困惑,因此以下是您需要执行的确切步骤:
就我而言,我这样做是:
index.php
<script src=\"/js/crm/lib/require.js\"></script>
<script>
// this is so called \"named define\"
define(\'dto\',{
page: JSON.parse(\'{{ pageDTO | json_encode }}\'),flashMessages: JSON.parse(\'{{ this.flashSession.getMessages() | json_encode }}\')
});
// note we are using relative path to public dir here
// order is also important,we need to define our dto module before bootstraping the application
require([\'/js/crm/app.js\']);
</script>
app.js
\"use strict\";
require.config({
// ...
baseUrl: \'/js/crm/lib\',paths: { app: \'../app\' }
});
require([\'app/bootstrap\']);
some-module.js
(在这种情况下,app / bootstrap中需要的layout.js)
\"use strict\";
define([
\'dto\',\'jquery\',\'lodash\'
],function (dto,$,_) {
console.log(dto);
});
请注意,使用race12ѭ引导应用程序,而无需显式调用require可能会起作用,但由于竞态条件。如果由于某种原因定义dto花费的时间超过了requirejs调用主模块脚本所花费的时间,那么它将崩溃。我们不想依靠它,所以我们自己做一切:)
因此,这有时行不通:
<script data-main=\"/js/crm/app.js\" src=\"/js/crm/lib/require.js\"></script>
<script>
// this is so called \"named define\"
define(\'dto\',flashMessages: JSON.parse(\'{{ this.flashSession.getMessages() | json_encode }}\')
});
</script>