将服务器数据传递给RequireJS模块的首选方法是什么?

时间:2011-05-24 02:27:10

标签: javascript jquery asp.net-mvc-3 requirejs

是否有一种在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"], function ($, page) {
    return {
        initialize: function () {
            console.log(page.guid);
            //logs guid as expected
        }
    }
});

6 个答案:

答案 0 :(得分: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;
});

答案 1 :(得分:3)

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

两种方法

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

  1. 为从服务器获取所需数据的'dao'或'service'模块建模 使其可供用户访问(类似于您当前的方法,请参阅下面的代码示例)
  2. 定义所有模块都有权访问的全局对象
  3. 第一个方法为您的函数添加参数。

    第二提供全局访问权限。这还需要您自己的初始化代码才能开始获取数据。

    归结为个人偏好以及你拥有的这些'dao'中有多少。如果您有多个,它可能会变为poluting,因为您需要为每个dao模块添加一个新参数。在这种情况下,使它们全球化似乎更清晰。

    您的方法存在问题

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

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

    这样,RequireJS将页面识别为一个模块,因为它是一个单独的文件,每页只会发送一次。

答案 2 :(得分:1)

如果你有一个JSON对象,请在评论中提到像@yves这样的AJAX调用。

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

老实说,我只是打电话给AJAX。

答案 3 :(得分:0)

使用窗口全局变量将服务器数据传输到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
});

答案 4 :(得分:0)

我今天刚开始使用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的过渡更容易。

答案 5 :(得分:0)

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

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

<强>的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']);

<强>一些-module.js

(在这种情况下是app / bootstrap中需要的layout.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>