【问题标题】:Backbone collection within model + restful server design using Node.js使用 Node.js 的模型 + RESTful 服务器设计中的主干集合
【发布时间】:2013-04-10 14:39:53
【问题描述】:

我正在尝试开发一个简单的文件浏览器,客户端使用 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. 如何表示模型对象本身。如果isDir===true,我应该将内容设置为 MyFile 的集合吗?如果是这种情况,我该怎么做?对模型的内容调用 toJSON() 会引发异常,因为未定义 toJSON
  2. 同样在MyFilesListView 上,它是否也应该收听全局集合?现在我需要处理子文件夹,这似乎不对。
  3. 或者我应该在尝试查看子文件夹时覆盖全局集合?
  4. 我的服务器代码实现是否正确?我现在遇到的问题是,当我将内容放入数组并将 fileModel 发送回客户端时,文件列表不会反映在模型本身中 - 也许我必须覆盖 parse

我在这里读了一些帖子

但我仍然不确定如何应用它... Javascript 令人困惑:(

【问题讨论】:

    标签: javascript node.js backbone.js backbone.js-collections


    【解决方案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语法更简单,更易读。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-30
      • 2015-08-31
      • 1970-01-01
      • 1970-01-01
      • 2013-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多