24

有没有首选的方法在 RequireJS 模块中传递服务器数据?我们当前的实现看起来像下面的代码片段;使用“页面”对象来保存任何服务器/动态数据并将其传递给主引导程序。(此时我们不想使用 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"], function ($, page) {
    return {
        initialize: function () {
            console.log(page.guid);
            //logs guid as expected
        }
    }
});
4

6 回答 6

4

我通常会做这样的事情(在后端使用 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;
});
于 2012-05-31T06:01:48.017 回答
3

RequireJS 没有说明如何处理服务器数据,因为它是一种模块化 javascript 的方法。所以在这方面没有事实上的标准,你可以根据需要将 RequireJS 与 json、ajax、php、嵌入式 xml 等结合起来。

两种方法

通常有两种方法可以解决这个问题。

  1. 为从服务器获取所需数据并使其用户可以访问的“dao”或“服务”模块建模(类似于您当前的方法,请参见下面的代码示例)
  2. 定义一个所有模块都可以访问的全局对象

一种方法将参数添加到您的函数中。

第二提供全球访问。这也需要您自己的初始化代码来开始获取数据。

这取决于个人喜好以及您拥有多少这些“道”。如果你有多个,它可能会变得有污染,因为你需要为每个 dao 模块添加一个新参数。在这种情况下,使它们全球化似乎更清洁。

你的方法有问题

但是,您当前的方法存在一个问题,您将 Page 模块作为定义(使用define()而不是require()),因为为依赖于它的每个对象创建了一个定义模块。这可能意味着同一页面内的多个调用。而是使用:

// in seperate file page.js:
require([], function () {
  return { guid: "<%=Guid.NewGuid() %>" };
});

这种方式 RequireJS 将页面识别为一个模块,因为它是一个单独的文件,并且每个页面只会访问您的服务器一次。

于 2012-05-30T10:02:08.477 回答
1

如果您有 JSON 对象,请像评论中提到的 @yves 一样进行 AJAX 调用。

如果您不想这样做,还有其他选择。您可以将 guid 作为数据属性放在 script 标签上。此外,您可以尝试使加载器 js 文件动态化,以便在其中设置配置。

不过老实说,我只是打一个 AJAX 调用。

于 2012-04-29T23:56:56.660 回答
1

我今天刚开始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 的转换更容易。

于 2013-10-02T20:23:17.673 回答
1

我发现一些答案令人困惑,因此以下是您需要遵循的确切步骤以使其适合您:

就我而言,我这样做是这样的:

索引.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

(在这种情况下,app/bootstrap 中需要 layout.js)

"use strict";

define([
    'dto',
    'jquery',
    'lodash'
], function (dto, $, _) { 
    console.log(dto);
});

请注意,使用data-main引导应用程序,无需显式调用 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', {
        page: JSON.parse('{{ pageDTO | json_encode }}'),
        flashMessages: JSON.parse('{{ this.flashSession.getMessages() | json_encode }}')
    });
</script>
于 2017-08-31T07:45:45.373 回答
0

使用 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
});
于 2013-09-20T07:14:45.707 回答