Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在使用AMD(require.js)时在Backbone.js中加载引导模型_Javascript_Backbone.js_Requirejs_Js Amd - Fatal编程技术网

Javascript 如何在使用AMD(require.js)时在Backbone.js中加载引导模型

Javascript 如何在使用AMD(require.js)时在Backbone.js中加载引导模型,javascript,backbone.js,requirejs,js-amd,Javascript,Backbone.js,Requirejs,Js Amd,Backbone.js文档建议通过以下方式加载引导模型: <script> var Accounts = new Backbone.Collection; Accounts.reset(<%= @accounts.to_json %>); var Projects = new Backbone.Collection; Projects.reset(<%= @projects.to_json(:collaborators => true) %>); <

Backbone.js文档建议通过以下方式加载引导模型:

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

var账户=新主干。集合;
Accounts.reset();
var Projects=新主干网集合;
项目。重置(正确)%>);
但这是一种不能在AMD方法中使用的模式(使用require.js)

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


有没有更好的方法来做这件事(没有globals)?

这样做怎么样:

<script>
define('Models', ['backbone'], function(Backbone) {
    var Models = {
        Accounts: new Backbone.Collection,
        Projects: new Backbone.Collection
    };

    Models.Accounts.reset(<%= @accounts.to_json %>);
    Models.Projects.reset(<%= @projects.to_json(:collaborators => true) %>);

    return Models;
});
</script>
var models = require(['Models']);
models.Accounts.doWhatYouNeed();
或者这个:

define(['any', 'dependencies', 'and', 'Models'], function(a, b, c, Models) {
   // Models will be available here
});

您可以在AMD模块的末尾添加一个循环函数,以检查何时定义了init方法(以便可以在body之后填充它,或者从include加载它)。这样可以保证模块可用,并且在准备就绪时可以进行初始化

require(...,function (...) {
   //define models collections, etc..

   var initme = function () {
     if(document.initThisModule) 
       document.initThisModule();
     else
       setTimeout(initme, 10);
   }();
});
我对AMD方法不太熟悉,但与其使用全局变量,不如将JSON添加到dom中

例如:

var json = ...,
$jsonContainer = $(json).wrap("<script id='json-container' type='text/javascript'>").appendTo($("body"));

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

在呈现的页面中

定义('config',函数(){
返回{
引导帐户:,
bootstrappedProjects:true)%%>
};
});
globals.js
此文件检查配置并使用返回的任何数据扩展自身

定义([
“配置”,
“下划线”
],函数(配置){
变量全局={
};
_.extend(全局,配置);
返回全局;
});
config.js
无论您是否在页面中定义了
config
,如果您希望能够加载应用程序,则需要此文件

define(函数(){
//页面中未定义“config”的情况的空数组
返回{};
});
app.js
需要([
“全球”,
“下划线”,
“骨干”
],函数(全局){
if(全局引导帐户){
var accounts=新主干.Collection(globals.bootstrappedAccounts);
}
if(globals.bootstrappedProjects){
var projects=new Backbone.Collection(globals.bootstrappedProjects);
}
});

看起来您可以使用require.config()函数或带有“config”选项的“require”全局函数,以便通过特殊依赖项“module”将数据传递给模块。见:

通常需要将配置信息传递给模块。那个 配置信息通常是应用程序的一部分,并且 需要有一种方法将其传递给模块。在《还魂曲》中, 这是通过requirejs.config()的config选项完成的。模块 然后可以通过请求特殊依赖项“模块”来读取该信息 并调用module.config()

因此,对于引导模型,在顶级HTML页面中:

<script>
var require = {
    config: {
        'app': {
            bootstrappedAccounts: <%= @accounts.to_json %>
            bootstrappedProjects: <%= @projects.to_json(:collaborators => true) %>
        }
    }
};
</script>
<script src="scripts/require.js"></script>
这里的“模块”是为这些类型的案例提供的特殊依赖项


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

这里的一些答案让我接近我的类似问题,但没有解决它。特别是排名靠前且被接受的答案似乎给了我一个恶劣的比赛条件,有时虚拟对象会先加载。当与Optimizer一起使用时,这种情况也会100%发生。它还为模块使用显式字符串名称,require文档特别建议您不要这样做

我是这样做的。与Brave Dave类似,我使用config对象捕获参数(在我的例子中是从jsp页面),如下所示

关键的一点是,config对象上必须有一个键mod.map.id解析为“options”的属性

从这里,您现在可以像这样访问模型

define(['module'], function(module){
    console.log(module.config().bootstrappedModels);
    //...
});

正如上面所描述的,“数据模块”(或配置,或任何你想叫它的东西)可以包含在已经生成的文件中(例如index.html),但我认为这相当难看

另一种方法是在其自己的模块文件中声明它,但这需要在生产环境中额外往返到服务器。只要您想要构建和优化您的requirejs依赖项,就不能包含数据模块,因为它是在页面加载时动态生成的


第三个选项可能是将其附加到您提供的一个文件(例如,优化的requirejs文件)中,但我不知道如何/是否可以这样做。

在requirejs中,这是通过
requirejs.config()的配置选项完成的。
。然后,模块可以通过请求特殊依赖项“module”并调用
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>
app.js

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

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


阅读有关此的文档:

Ansewr by@dlrust-work,但它无法扩展参数并从代码中的一个位置传递多个参数。如果尝试在渲染模板中执行以下操作:

<script>
    define('config', function() {
        return {
            bootstrappedAccounts: <%= @accounts.to_json %>,
            bootstrappedProjects: <%= @projects.to_json(:collaborators => true) %>
        };
    });
</script>
global.js
index.php
index.js
文件结构:

意识到这不是一个答案,移动到评论:我使用require.js和bootstrap。我基本上做了你不想做的事。第一个获取的页面具有我引导的JSON数据的全局变量。我复制/使用这些值填充初始模型和集合。我不确定这是不是一种不好的方式。如果你担心会污染全局空间,你不能先删除这些变量吗
<script>
  var require = {
    config: {
      'app': {
        'api_key': '0123456789-abc'
      }
    }
  };
</script>
<script src="js/libs/require.js" data-main="js/main"></script>
require( ['app'], function(App) {
  new App();
});
define( ['module'], function(module) {
  var App = function() {
    console.log( 'API Key:', module.config().api_key );
  };

  return App;
});
<script>
    define('config', function() {
        return {
            bootstrappedAccounts: <%= @accounts.to_json %>,
            bootstrappedProjects: <%= @projects.to_json(:collaborators => true) %>
        };
    });
</script>
<script>
    define('config', function() {
        return {
            goods: <%= some data %>,
            showcaseList: <%= some json or array %>
        };
    });
</script>
define("App", [], function() {
    window.App = {
        // модели
        Model: {},
        // коллекции
        Collection: {},
        // виды
        View: {},
        // роутеры
        Router: {},
        // модальные окна
        Modal: {},
        // UI компоненты
        UI: {}
    };
    return window.App;
});
define(["App", "underscore", "backbone"], function(App, _, Backbone) {
    "use strict";

    // модель глобальных данных
    App.Model.Global = Backbone.Model.extend({
        defaults: {}
    });

    return new App.Model.Global;    
});
<!DOCTYPE html>
<html>
    <head>
        <!--HEAD_START-->
        <script type="text/javascript" data-main="/app/init" src="/app/require/require.js"></script>
        <!--HEAD_END-->
    </head>

    <body>          
        <div id="tm-inner-wrap">
            <div id="loader"><i class="uk-icon-refresh uk-icon-spin"></i></div>
            <!--HEADER_START-->
            <?= $this->includeTpl('header_view'); ?>
            <!--HEADER_END-->

            <!--CONTENT_START-->
            <div>your html content data</div>
            <!--CONTENT_END-->

            <!--FOOTER_START-->
            <?= $this->includeTpl('footer_view');?>
            <!--FOOTER_END-->

            <script>
                require(["global"], function(Global) {
                    Global.set("notifyList", <?=json_encode($this->notifyList);?>);
                });
            </script>
        </div>
    </body>
</html>
<div class="tm-inner-body">
    <div class="uk-container uk-container-center">
        // content data
    </div>
</div>

<script>    
    require(["global", "module/index"], function(Global) {
        Global.set("goodList", <?=json_encode($this->goodList);?>);
    });
</script>
require(["App", "core", "jquery", "uikit!uikit-addons-min", "underscore", "backbone", "global", "module/good/goodView"], function(App, Core, $, UIkit, _, Backbone, Global, goodView) {
    "use strict";

    // Global.get("notifyList"); its too able

    App.Collection.Good = new Backbone.Collection(Global.get("showcaseList")["items"]);

    // вид списка товаров
    App.View.GoodList = Backbone.View.extend({
        // елемент
        el: ".tm-good-list",
        // init
        initialize: function() {
            this.collection = App.Collection.Good;
            // список товаров
            this.drawList();
        },
        // отрисовка списка
        drawList: function() {
            this.$el.empty();
            this.collection.each(function(item, index) {
                this.$el.append(this.drawItem(item));
            }, this);
        },
        // отрисовка елемента
        drawItem: function(data) {
            var good = new goodView({model: data});
            return good.render().el;
        }
    });

    App.View.Index = Backbone.View.extend({
        el: "body",
        // пользовательские события
        events: {
            //
        },
        // init
        initialize: function() {
            var $this = this;
            if(Global.get("showcaseList")) new App.View.GoodList();
        }
    });

    new App.View.Index();
});