如何在使用AMD时加载Backbone.js中的自举模型(require.js)

ope*_*rid 53 javascript requirejs backbone.js js-amd

Backbone.js文档建议以这种方式加载bootstrapped模型:

<script>
var Accounts = new Backbone.Collection;
Accounts.reset(<%= @accounts.to_json %>);
var Projects = new Backbone.Collection;
Projects.reset(<%= @projects.to_json(:collaborators => true) %>);
</script>
Run Code Online (Sandbox Code Playgroud)

但这是一种不能用于AMD方法的模式(使用require.js)

唯一可能的解决方案是声明存储JSON数据的全局变量,并在稍后的相关初始化方法中使用此变量.

有没有更好的方法来做到这一点(没有全局变量)?

dlr*_*ust 71

这就是我们以不污染全局命名空间的方式引导数据的方式.相反,它只使用require.js.它还可以帮助您根据模板中的变量提供初始应用程序配置.

在您呈现的页面中

<script src="require.js"></script>
<script>
define('config', function() {
  return {
    bootstrappedAccounts: <%= @accounts.to_json %>,
    bootstrappedProjects: <%= @projects.to_json(:collaborators => true) %>
  };
});
</script>
<script src="app.js"></script>
Run Code Online (Sandbox Code Playgroud)

globals.js

此文件检查config并使用返回的任何数据扩展自身

define([
  'config',
  'underscore'
], function(config) {

  var globals = {
  };
  _.extend(globals, config);
  return globals;

});
Run Code Online (Sandbox Code Playgroud)

config.js

如果您希望能够加载应用程序,无论您是否已config在页面中定义,都需要此文件.

define(function() {
  // empty array for cases where `config` is not defined in-page
  return {};
});
Run Code Online (Sandbox Code Playgroud)

app.js

require([
  'globals',
  'underscore',
  'backbone'
], function(globals) {

  if (globals.bootstrappedAccounts) {
    var accounts = new Backbone.Collection(globals.bootstrappedAccounts);
  }
  if (globals.bootstrappedProjects) {
    var projects = new Backbone.Collection(globals.bootstrappedProjects);
  }

});
Run Code Online (Sandbox Code Playgroud)

  • 这是为我工作的设置,我为了使它与优化器一起工作是为了'excludeShallow`我的config.js那样它将始终使用html中定义的模块 (3认同)

Bra*_*ave 31

看起来您可以使用require.config()函数或"require"全局和"config"选项,以便通过特殊依赖"模块"将数据传递给模块.见http://requirejs.org/docs/api.html#config-moduleconfig:

通常需要将配置信息传递给模块.该配置信息通常被称为应用程序的一部分,需要有一种方法将其传递给模块.在RequireJS中,使用requirejs.config()的config选项完成.然后,模块可以通过询问特殊依赖"模块"并调用module.config()来读取该信息.

因此,对于bootstrapping模型,我们在顶级HTML页面中:

<script>
var require = {
    config: {
        'app': {
            bootstrappedAccounts: <%= @accounts.to_json %>
            bootstrappedProjects: <%= @projects.to_json(:collaborators => true) %>
        }
    }
};
</script>
<script src="scripts/require.js"></script>
Run Code Online (Sandbox Code Playgroud)

然后在app模块(app.js)中,我们有:

define(['module'], function (module) {
    var accounts = new Backbone.Collection( module.config().bootstrappedAccounts );
    var bootstrappedProjects = new Backbone.Collection( module.config().bootstrappedProjects );
});
Run Code Online (Sandbox Code Playgroud)

这里"模块"是为这些类型的案例提供的特殊依赖.

这是未经测试的,但从文档中看起来非常确定.

  • 很好的解决方案,对我有用,也应该与优化器一起工作(还没有到目前为止).我注意到''app'`对应于加载对象的模块,所以如果你想在另一个模块中使用bootstrapped数据(例如`otherModule.js`),它需要在`config:{'中. otherModule':otherModuleBootstrapData}` (5认同)

Tom*_*Doe 11

在RequireJS中,这是通过config选项完成的requirejs.config().然后,模块可以通过询问特殊依赖"模块"和调用来读取该信息module.config().例:

的index.html

<script>
  var require = {
    config: {
      'app': {
        'api_key': '0123456789-abc'
      }
    }
  };
</script>
<script src="js/libs/require.js" data-main="js/main"></script>
Run Code Online (Sandbox Code Playgroud)

main.js

require( ['app'], function(App) {
  new App();
});
Run Code Online (Sandbox Code Playgroud)

app.js

define( ['module'], function(module) {
  var App = function() {
    console.log( 'API Key:', module.config().api_key );
  };

  return App;
});
Run Code Online (Sandbox Code Playgroud)

请注意,配置对象的名称必须与模块的名称匹配.在我的示例中,模块的名称是app,因此配置对象的名称也需要命名app.在模块中,您需要包含['module']作为依赖项和调用module.config()[property name]来检索配置数据.

阅读有关此文档的文档:http://requirejs.org/docs/api.html#config-moduleconfig


Oll*_*rds 6

这里的一些答案让我接近我的类似问题,但没有任何东西钉它.特别是排名靠前和接受的答案似乎给了我一个讨厌的竞争条件,有时虚拟对象将首先加载.当与优化器一起使用时,这也发生在100%的时间.它还为模块使用显式字符串名称,需要文档特别建议您不要这样做.

这就是我的工作方式.与Brave Dave类似,我使用config对象来捕获参数(在我的情况下来自jsp页面),就像这样

<script type="text/javascript">
    var require = {
        config: {
            options : { 
                bootstrappedModels : ${models}
            }
        }
    }
</script>
Run Code Online (Sandbox Code Playgroud)

特别要注意我的参数位于一个名为options的对象中.这个名字不是可选的!虽然文档没有提到这一点,但以下是require如何加载你的配置(requirejs 2.1.1中的第564行):

config: function () {
    return (config.config && config.config[mod.map.id]) || {};
},
Run Code Online (Sandbox Code Playgroud)

关键点是配置对象上必须有关键mod.map.id的属性,该关键字解析为'options'.

从这里您可以访问这样的模型

define(['module'], function(module){
    console.log(module.config().bootstrappedModels);
    //...
});
Run Code Online (Sandbox Code Playgroud)