Backbone.js查看多个集合和排序

时间:2015-09-28 20:36:35

标签: backbone.js backbone-views backbone-collections

我有一个包含多个集合的视图,实现如下:

collection: {
   folders: new FolderCollection(),
   images: new ImageCollection(),
   files: new FileCollection()
},

示例集合是这样的:

var FolderCollection = Backbone.Collection.extend({
    model: folderObj,
    initialize:function (){
        // this.bindAll(this);
        // this.setElement(this.at(0));
    },
    comparator: function(model) {
        return model.get("id");
    },
    getElement: function() {
        return this.currentElement;
    },
    setElement: function(model) {
        this.currentElement = model;
    },
    next: function (){
        this.setElement(this.at(this.indexOf(this.getElement()) + 1));
        return this;
    },
    prev: function() {
        this.setElement(this.at(this.indexOf(this.getElement()) - 1));
        return this;
    }
});

可以想象,此视图是文件,图像和文件夹的显示。然后我通过调用三个不同的函数来填充视图;一个用文件夹填充视图,另一个用于文件,另一个用于图像。这些函数中的每一个都是单独的ajax请求。因此,因为这些调用是异步的,所以没有办法首先加载文件夹,然后是图像,然后是文件,并且在页面加载时没有一致性。

所以,我的问题是,我需要能够以多种方式订购这三个集合。第一个问题是,由于调用是异步的,有时文件夹首先加载,或者文件等等。我可以想到两种解决方法:

  1. 仅在上一个功能完成后调用下一个功能。这是最好的方法吗?如果是这样,我该怎么做

  2. 加载所有集合后,对它们进行排序。如果是这样,对多个集合进行排序和排序的最佳方法是什么?

  3. 如果需要更多代码(例如:型号或视图),请告诉我,我可以提供所需的代码。

    感谢 杰森

    编辑 - 显示视图

    var FileManagementView = TemplateView.extend({
        viewName: 'fileManagement',
        className: 'fileManagement',
        events: {
                //my events
    
        },
        collection: {
            folders: new FolderCollection(),
            images: new ImageCollection(),
            files: new FileCollection()
        },
        //life cycle
        initialize: function (options) {
            TemplateView.prototype.initialize.apply(this, [options]);      
    
        },
        templateContext: function (renderOptions) {   
        },
    
        postRender: function () {
            //more functions to set up the view
            this.repopulateViewWithFoldersAndFiles(currentFolderId);
        },
        template: function (renderOptions) {
            return 'MyMainTemplate';
        },
        repopulateViewWithFoldersAndFiles: function(currentFolderId){
            //code to do stuff to create view
    
            //these functions are all async, so theres no way to know what will finish first
            this.getFolders(currentFolderId);
            this.getImages();
            this.getFiles();
    
        },
        getFiles: function(){
            try{
                var that = this;
                var url = '?q=url to function';
    
                $.ajax({
                    url: url,
                    context: that,
                    data:{'methodName': 'getFiles'}
                }).done(function(data) {
                    var results =  jQuery.parseJSON(data.result.results);
                    if(results){
                        $.each(results, function( key, value ) {
                             var file = new fileObj;
                            file.set('id', value.id);
                            file.set('fileName', value.fileName);
                            //...set more attributes
                            that.collection.files.add(file);
                            that.renderFile(file);
                        });
                    }
                });
            }  catch(e){
                throw e;
            }
        },
    
        renderFile: function(file){
            try{
                if(file) {
                    var template = window.app.getTemplate('AnotherTemplate');
                    var html = $(template({
                        id: file.get('id'),
                        fileName: file.get('fileName'),
                        fileIconPath: file.get('fileIconPath')
    
                    }));
                    this.$el.find('#fileDropZone').append(html);
                }
            }  catch(e){
                throw e;
            }
        },    
        getImages: function(){
            try{            
                var url = '?q=url to function';
                $.ajax({
                    url: url,
                    context: that,
                    data:{'methodName': 'getImages'}
                }).done(function(data) {
                    var results =  jQuery.parseJSON(data.result.results);
                    if(results){
                        $.each(results, function( key, value ) {                        
                            var image = new imageObj;
                            image.set('id', value.id);
                            image.set('imgTitle', value.image_name);
                            //....set more attributes
                            that.collection.images.add(image);
                            that.renderImage(image);
                        });
                    }
                });
            }  catch(e){
                throw e;
            }
        },
        renderImage: function(image){
            try{
                if(image) {
                    var template = window.app.getTemplate('myViewTemplate');
                    var html = $(template({
                        imgId: image.get('id'),
                        imgTitle: image.get('imgTitle'),
                        //..more attributes
                    }));
                    this.$el.find('#fileDropZone').append(html);
                }
            }  catch(e){
                throw e;
            }
        },       
        getFolders:function(parentId){
            var that = this;
            var url = '?q=...path to function';
    
            $.ajax({
                url: url,
                context: that,
                data:{'methodName': 'getFolders'}
            }).done(function(data) {
                var results =  jQuery.parseJSON(data.result.results);
                if(results){
                    $.each(results, function( key, value ) {
                        var folder = new folderObj();
                        folder.set('folderName', value.folder_name);                    
                        folder.set('id', value.folder_id);
                        //more attributes
                        that.collection.folders.add(folder);
                        that.renderFolders(folder);
                    });
                }else{
                    this.renderFolders(null);
                }
            });
        },
        //renders the folders to the view
        renderFolders: function(folder){
            try{
                if(folder) {
                    var template = window.app.getTemplate('myFolderTemplate');
                    var html = $(template({
                        folderId: folder.get('id'),
                        folderName: folder.get('folderName'),                 
                    }));
                    this.$el.find('#fileDropZone').append(html);
                }
            }  catch(e){
                throw e;
            }
        }   
    });
    

1 个答案:

答案 0 :(得分:0)

我最终做的是重写我的模型并创建一个其他人继承的模型。例如:

var DataModel =MyBaseModel.extend({
    defaults: {
        id: null,
        //other shared fields
    }
});

我继承的所有其他模型都是这样的:

var folderObj = DataModel.extend({
    // Whatever you want in here
    urlRoot: '?q=myApp/api/myClassName/',
    defaults: {
        //other fields here

    },
    validate: function(attributes){
          //validation here
    }
});

然后我使用了延迟,我在这里回答:Jquery Promise and Defered with returned results