Marionette js itemview没有定义:然后在浏览器刷新它定义并且一切正常 - 竞争条件?

时间:2013-10-25 03:49:11

标签: collections requirejs marionette race-condition

是的,只是初始浏览器加载或缓存清除后的两个。随后的刷新可以解决问题。

我认为项目视图并没有及时完全构建,无法在第一次加载的集合视图中使用。但他们正在刷新?不知道。

必须有关于代码序列或加载或加载时间本身的内容。不确定。我是通过require.js加载的。

有两个集合 - 用户和消息。每个渲染都在自己的集合视图中。每个都可以工作,而不是第一次或两次浏览器加载。

首次在清除浏览器缓存后加载控制台报告,例如:

“未捕获的ReferenceError:未定义MessageItemView”

简单的浏览器刷新会将其清除。用户集合也是如此。它的集合视图表示它对项目视图一无所知。但是一个简单的浏览器刷新,一切都很好。

我的观点(项目和集合)位于单独的文件中。那是问题吗?例如,这是我自己的文件中的消息集合视图:

messagelistview.js

    var MessageListView = Marionette.CollectionView.extend({
        itemView: MessageItemView,
        el: $("#messages")
    });

消息项视图位于单独的文件中:

messageview.js

    var MessageItemView = Marionette.ItemView.extend({
        tagName: "div",    
        template: Handlebars.compile(
                '<div>{{fromUserName}}:</div>' +
              '<div>{{message}}</div>' +
        )
    });

然后在我的主模块文件中,它引用了每个文件,构建并显示了集合视图:

main.js

    //Define a model
    MessageModel = Backbone.Model.extend();

    //Make an instance of MessageItemView - code in separate file, messagelistview.js
    MessageView = new MessageItemView();


    //Define a message collection 
    var MessageCollection = Backbone.Collection.extend({
        model: MessageModel    
    });

    //Make an instance of MessageCollection
    var collMessages = new MessageCollection(); 


    //Make an instance of a MessageListView -  code in separate file, messagelistview.js
    var messageListView = new MessageListView({
        collection: collMessages
    });

    App.messageListRegion.show(messageListView);

我只是把事情排序错了吗?我认为这只是一种竞争条件,因为在3G上,iPad的项目视图总是未定义的。他们似乎永远不会及时建造。浏览器刷新或刷新两次后,硬连线上的PC确实会看到成功。它可能是加载时间还是浏览器的差异? PC上的Chrome IE和Firefox似乎都表现出刷新行为的成功。 iPad上的Safari总是失败。

以下评论,这是我的要求: 在文件application.js

    require.config({
        paths: {
            jquery: '../../jquery-1.10.1.min',
            'jqueryui': '../../jquery-ui-1.10.3.min',
            'jqueryuilayout': '../../jquery.layout.min-1.30.79',
            underscore: '../../underscore',
            backbone: '../../backbone',
            marionette: '../../backbone.marionette',
            handlebars: '../../handlebars',
            "signalr": "../../jquery.signalR-1.1.3",
            "signalr.hubs": "/xyvidpro/signalr/hubs?",        
            "debug": '../../debug',
            "themeswitchertool": '../../themeswitchertool'
        },

        shim: {
            'jqueryui': {
                deps: ['jquery']
            },

            'jqueryuilayout': {
                deps: ['jquery', 'jqueryui']
            },

            underscore: {
                exports: '_'
            },

            backbone: {
                deps: ["underscore", "jquery"],
                exports: "Backbone"
            },

            marionette: {
                deps: ["backbone"],
                exports: "Marionette"
            },        

            "signalr": {
                deps: ["jquery"],
                exports: "SignalR"
            },

            "signalr.hubs": {
                deps: ["signalr"],
                exports: "SignalRHubs"
            },

            "debug": {
                deps: ["jquery"]
            },

            "themeswitchertool": {
                deps: ["jquery"]
            }
        }
    });


    require(["marionette", "jqueryui", "jqueryuilayout", "handlebars", "signalr.hubs", "debug", "themeswitchertool"], function (Marionette) {
        window.App = new Marionette.Application();

        //...more code

    })

最后,在使用的模块内部创建有问题的集合视图,外部文件依赖项列表如下:

    var dependencies = [
        "modules/chat/views/userview",
        "modules/chat/views/userlistview",
        "modules/chat/views/messageview",
        "modules/chat/views/messagelistview"
    ];

显然,itemViews在collectionViews之前列出。这对我来说似乎是正确的。在定义之前,不确定collectionViews需要itemViews的原因。为什么浏览器刷新后一切正常?

1 个答案:

答案 0 :(得分:1)

加载文件的顺序很可能是错误的:您需要在集合视图之前加载项目视图。

尝试按正确的顺序将所有代码放在同一个文件中,看看它是否有效。

free previewmy book on Marionette还可以指导您显示集合视图。

根据校准进行编辑:

不会线性加载为模块列出的依赖项。这正是RequireJS旨在避免的。相反,正确加载文件(即按正确顺序)的方法是定义RequireJS将计算和加载的依赖关系“链”。

您需要做的是定义(例如)您的用户列表视图以依赖于用户视图。通过这种方式,它们将通过RequireJS以正确的顺序加载。您可以看到RequireJS应用here的示例(来自book on RequireJS and Marionette)。看看每个模块定义如何分解它依赖的模块(因此RequireJS需要加载)。再一次,在依赖数组中按顺序列出模块不会使它们按顺序加载,你真的需要使用依赖链机制。