4

クライアントにBackbone、サーバーにNode.jsを使用して、単純なファイルブラウザを開発しようとしています。現時点では、サブフォルダーに関してモデルを設計する方法にかなりこだわっています

クライアントコードは次のようになります

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. モデル オブジェクト自体を表現する方法。場合は、コンテンツを MyFile のコレクションに設定する必要がありますisDir===trueか? この場合、どのようにすればよいですか?が定義されていないtoJSON()ため、モデルのコンテンツを呼び出すと例外がスローされますtoJSON
  2. またMyFilesListView、グローバル コレクションも聞く必要がありますか? サブフォルダーを処理する必要があるので、正しくないようです。
  3. または、サブフォルダーを表示しようとするときにグローバル コレクションをオーバーライドする必要がありますか?
  4. サーバーコードの実装は正しいですか? 私が今抱えている問題は、コンテンツを配列に入れて fileModel をクライアントに送り返すと、ファイルのリストがモデル自体に反映されないことです-おそらくオーバーライドする必要がありますparseか?

ここでいくつかの投稿を読みました

しかし、私はまだそれを適用する方法がわかりません.Javascriptは混乱しています:(

4

1 に答える 1

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

より魔法のようなことを行うもう 1 つの方法は、リレーショナル モデルを使用することです (そのような機能を提供するバックボーン拡張による)。

についてもっと読みたい場合:

同じことを行う marionette.js の例

Backbone.Relational - bakcbone のリレーショナル拡張

PS : これ以上のリンクは提供できません。Backbone.associate を検索してください。これは、backbone の別のリレーショナル拡張です。

PS 2 : コーヒースクリプトを使用すると、javascript 構文がよりシンプルで読みやすくなります。

于 2013-04-11T00:06:23.310 に答える