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

发布于 2024-11-09 07:44:22 字数 773 浏览 4 评论 0原文

是否有在 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
        }
    }
});

Is there a preferred way to pass server data in a RequireJS module? Our current implementation looks like the following code snippets; using a 'page' object to hold any server/dynamic data and passing that to the main bootstrap. (We don't want to use ajax to populate any dependencies at this time)

From a server page :

<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
        }
    }
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

谈下烟灰 2024-11-16 07:44:22

我通常会做这样的事情(在后端使用 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;
});

I usually do something like this (using PHP on the back-end but anything works):

<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>

And then define my module as something that takes a config:

define(['jquery'], function($) {
  var App = function(options) {
    this.options = options;
    //blabla
  }

  // add some stuff to App.prototype maybe

  // and finally...
  return App;
});
溺孤伤于心 2024-11-16 07:44:22

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

两种方法

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

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

first 方法向您的函数添加参数。

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

这取决于个人喜好以及你拥有多少这样的“道”。如果您有多个 dao 模块,则可能会造成污染,因为您需要为每个 dao 模块提供一个新参数。在这种情况下,让它们全球化似乎更干净。

您的方法有问题

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

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

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

RequireJS says nothing about how to deal with server data, as it is a means to modularize your javascript. So in that regard there is no defacto standard and you can combine RequireJS with json, ajax, php, embedded xml etc however you want.

Two Approaches

There generally are two ways to go about this.

  1. Model a 'dao' or 'service' module that gets the required data from the server and
    makes it accessible to its users (similar to your current approach, see code sample below)
  2. Define a global object to which all modules have access

The first approach adds parameters to your functions.

The second provides global access. This also requires your own initialization code to start fetching data.

It comes down to personal preference and how many of these 'dao's' you have. If you have more than one it might become poluting as you need a new parameter for each dao module. In that case making them global seems cleaner.

A problem with your approach

There is a problem with your current approach though, where you have the Page module as a definition (using define() instead of require()), because a define module is created for each object that depends on it. This potentially means multiple calls within the same page. Instead use:

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

This way RequireJS recognizes page as a module because it is a seperate file and it will go to your server only once per page.

网名女生简单气质 2024-11-16 07:44:22

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

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

老实说,我只是进行 AJAX 调用。

If you have a JSON object, make an AJAX call like @yves mentioned in the comments.

There are other options if you don't want to do that. You could put the guid as a data attribute on the script tag. Also, you could try making the loader js file dynamic so the config is set in that.

Honestly though, I'd just make an AJAX call.

梦里人 2024-11-16 07:44:22

我今天刚刚开始使用 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。

I just started today with RequireJS and prior to this I was used to just call the function I wanted to execute on page load like this:

<script>
my_method(<?php echo json_encode( array('opt1'=>true, 'opt2'=>false) );?>);
</script>

As @ziad-saab I've found that the most similar thing I can do is not using the data-main attribute and just define an inline module:

<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>

The data-main attribute instructs RequireJS to execute the module as soon as require.js and all module dependecies are loaded. Omitting it (the module) and just defining it as an inline module I'm able to throw in PHP variables.

This way I don't need to handle with modules that hold my configurations and the transition to use requirejs is easier in my environment.

独自←快乐 2024-11-16 07:44:22

我发现一些答案令人困惑,因此您需要遵循以下具体步骤才能使其适合您:

在我的情况下,我这样做是这样的:

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);
});

注意使用 < code>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>

I have found some of the answers confusing, so here are the exact steps you need to follow to make it work for you:

In my case I am doing this like so:

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

(in this case layout.js that is required in app/bootstrap)

"use strict";

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

Note using data-main to bootstrap the application, without explicit call to require might work, but due to race condition. If defining dto for some reason would take more than it takes requirejs to call main module script will crash. We don't want to rely on that, so we do everything ourselves :)

So this would not work (sometimes):

<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>
揪着可爱 2024-11-16 07:44:22

使用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
});

Use window global variable to transfer server data into js application:

 <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>

in 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
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文