将服务器数据传递给 RequireJS 模块的首选方法是什么?
What is the preferred method for passing server data to a RequireJS module?
有没有在 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>
主.js
require(["jquery", "jquery.alpha", "page"], function ($, alpha, page) {
alpha.initialize(page);
});
jquery.apha.js
define(["jquery", "page"], function ($, page) {
return {
initialize: function () {
console.log(page.guid);
//logs guid as expected
}
}
});
我通常会做这样的事情(在后端使用 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;
});
RequireJS没有提到如何处理服务器数据,因为它是模块化javascript的一种手段。所以在这方面没有事实上的标准,你可以将RequireJS与json,ajax,php,embedded xml等结合起来。
两种方法
通常有两种方法可以做到这一点。
- 对从服务器获取所需数据的"dao"或"服务"模块进行建模,并使其用户可以访问(类似于您当前的方法,请参阅下面的代码示例)
- 定义所有模块都有权访问的全局对象
第一种方法向函数添加参数。
第二个提供全局访问。这也需要您自己的初始化代码才能开始获取数据。
这归结为个人喜好以及您有多少这样的"道"。如果您有多个模块,则可能会变得污染,因为您需要为每个 dao 模块创建一个新参数。在这种情况下,将它们全球化似乎更干净。
您的方法有问题
但是,您当前的方法存在一个问题,您将Page模块作为定义(使用define()
而不是require()
),因为为每个依赖于它的对象创建了一个定义模块。这可能意味着同一页面中的多个调用。而是使用:
// in seperate file page.js:
require([], function () {
return { guid: "<%=Guid.NewGuid() %>" };
});
通过这种方式,RequireJS 将页面识别为一个模块,因为它是一个单独的文件,并且每个页面只会转到您的服务器一次。
如果您有 JSON 对象,请按照注释中提到的@yves进行 AJAX 调用。
如果您不想这样做,还有其他选择。可以将 guid 作为数据属性放在脚本标记上。此外,您可以尝试使加载器 js 文件动态化,以便在其中设置配置。
老实说,我只是打一个AJAX电话。
我今天刚开始使用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
在需要时尽快执行模块.js并加载所有模块依赖项。省略它(模块)并将其定义为内联模块,我可以放入PHP
变量。
这样,我就不需要处理保存我的配置的模块,并且在我的环境中过渡到 requirejs 更容易。
我发现一些答案令人困惑,所以以下是您需要遵循的确切步骤,以使其为您工作:
就我而言,我是这样做的:
索引.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>
应用.js
"use strict";
require.config({
// ...
baseUrl: '/js/crm/lib',
paths: { app: '../app' }
});
require(['app/bootstrap']);
某模块.js
(在这种情况下.js在应用程序/引导程序中需要布局)
"use strict";
define([
'dto',
'jquery',
'lodash'
], function (dto, $, _) {
console.log(dto);
});
注意 使用 data-main
引导应用程序,而不显式调用 require,可能会起作用,但由于争用条件。如果由于某种原因定义 dto 需要比调用主模块脚本所需的更多时间,脚本将崩溃。我们不想依赖它,所以我们自己做所有事情:)
所以这行不通(有时):
<script data-main="/js/crm/app.js" 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 }}')
});
</script>
使用窗口全局变量将服务器数据传输到 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>
在应用中.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
});
- 打破承诺链的好方法是什么
- 在JavaScript中拆分日期字符串的更好方法是什么
- 将jQuery.ech()方法转换为本地JavaScript抽象的最佳方法是什么
- 处理浮点错误的最佳方法是什么
- 基于窗口宽度jquery的函数的替代方法是什么
- knex:根据结果创建数组的合适方法是什么
- 以编程方式填充组合框道场 (1.8) 的最佳方法是什么?
- 使用Modernizr检测移动设备最可靠的方法是什么
- 确定var是否是javascript中的elementFinder对象的方法是什么
- 用javascript修复这个JSON对象字符串最干净的方法是什么
- 让会话值可用于JavaScript的好方法是什么
- 从AngularJs获取谷歌地图对象的正确方法是什么
- 使用ReactJS和Flux架构从服务器获取数据的正确方法是什么
- 列出没有 mysql 的元素的最佳方法是什么
- 克服错误的更优雅的方法是什么:需要对象说明符.当通过JXA通过Messages发送SMS时,参数没有对象说明符
- 使用较少代码隐藏和显示选择菜单内容的更好方法是什么?javascript
- 在 Javascript 中实现解耦代码/回调的正确方法是什么?
- 使用Javascript,获取元素的方法是什么,基于打开和关闭标记之间的文本
- 在d3.json中使用d3.csv组合多个csv文件数据输入的最佳方法是什么
- 直接在DOM事件处理程序中调用作用域函数的最短方法是什么