2013-04-10 39 views
4

我正在嘗試開發一個簡單的文件瀏覽器,它使用客戶端的Backbone和服務器的Node.js。此刻我很卡如何當涉及到子文件夾模型中的骨幹集合+使用Node.js的restful服務器設計

客戶端代碼設計的模型看起來像

app.MyFile = Backbone.Model.extend({ 
    defaults: { 
     path: '', // id of the model will be the path + filename 
     content: '', // content of the file 
     isDir: false // if file is a directory 
    } 
}); 

var MyFileList = Backbone.Collection.extend({ 
    model: app.MyFile, 
    url: '/api/files' 
}); 

// create global collection of files 
app.MyFiles = new MyFileList(); 

// displays file name 
var MyFileItemView = Backbone.View.extend({ 
    events: { 
     'click .clickable': 'view' 
    }, 

    ... 

    view: function (source) { 
     if (this.model.toJSON().isDir) { 
      this.model.fetch(); 
      // XXX what to do here 

      _.each(this.model.get('content'), function (obj) { 
       console.log(obj.toJSON()); // error - no toJSON method 
      }); 

     } else { 
      // calls another view that calls the model.fetch 
      // to display the content (no issue here) 

     } 
    }, 
}); 


var MyFilesListView = Backbone.View.extend({ 
    initialize: function() { 
     // XXX Not sure if I should listen on MyFiles collection... 
     app.MyFiles.on('reset', this.render, this); 
    }, 

    render: function() { 
     app.MyFiles.each(function (file) { 
     new MyFileItemView({model:file}); 
     }, this); 

}); 

app.AppView = Backbone.View.extend({ 
    initialize: function() { 
    // fetch all files 
    app.MyFileList.fetch(); 
    } 
}); 

// app.js (point of entry) 
$(function() { 
    // Kick things off by creating the **App**. 
    new app.AppView(); 
}); 

我的服務器代碼:

var express = require("express"), 

... 

app.get('/api/files', function(req, res) { 
    ... 
    // return file list (including folder - no issue here) 
} 

app.get('/api/files/:id', function(req, res) { 
    var fileModel = createFileModel(req.params.id); // create file model 

    if (!fileModel.isDir) { 
     // if file is not directory, then simply read the content and return 
     // it back to the client -- no issue 
     ... 
    } else { 
     var files = []; 
     // read the directory to find all the files and push it to 
     // files array 
     ... 

     fileModel.content = files; 
     res.send(fileModel); 
    } 
} 

目前我我不確定什麼是正確的做法。我的問題:

  1. 如何表示模型對象本身。如果isDir===true?我應該將內容設置爲MyFile的集合嗎?如果是這樣的話,我該怎麼做?在模型的內容上調用toJSON()會拋出異常,因爲toJSON未定義
  2. 還應該在MyFilesListView上偵聽全局集合嗎?現在我需要處理子文件夾,這看起來不正確。
  3. 或者我應該在嘗試查看子文件夾時覆蓋全局集合嗎?
  4. 我的服務器代碼實現是否正確?我現在遇到的問題是,當我將內容放入數組並將fileModel發送回客戶端時,文件列表未反映在模型本身中 - 可能我必須覆蓋parse

我看了一些帖子這裏

但我仍然不知道如何使用它... JavaScript是令人困惑: (

回答

1

你可以在模型中用一個簡單的函數寫一個簡單的模型,就像你在單一模型中一樣(你可以稱之爲xfile模型! ):

loadFolders : function() { 
    if (this.get('isDir')) { 
     var self = this; 
     self.subFolders = []; 
     _.each(self.get('files'), function(data) { 
     file = new File(data); 
     self.subFolders.push(file); 
     }); 
    } 
    } 

並在您的視圖模型中執行相同的操作以呈現正確的樹視圖。

而在你的express.js後端(我不熟悉這個框架),你只需發送適當的json到你的骨幹模型。

如果您的數據太長,並且您想單獨獲取每個模型目錄(當用戶在您的視圖中展開文件夾時),您可以使用相同的想法創建包含大量集合(或具有大量集合的集合)的模型,然後從模型中的服務器獲取數據,後端必須支持目錄,如下所示:/ api/file/folder1/folder2/file1。TXT

另一種方式做一些事情是使用關係模型(通過任何骨幹網的擴展,提供這種功能)更神奇

如果您想了解更多有關:

A marionette.js example that do the same

Backbone.Relational - a relational extension for bakcbone

PS:我無法提供更多鏈接,因此您可以搜索Backbone.associate,這是另一個用於主幹的關係擴展

PS 2:您可以使用coffeescript,使其JavaScript語法更簡單,更具可讀性。