【问题标题】:When do I need a model in backbone.js?我什么时候需要backbone.js 中的模型?
【发布时间】:2012-10-25 13:02:18
【问题描述】:

我是 Backbone.js 的新手,并且是从 JS 开发的“标准”模型中走出来的人,我有点不确定如何使用这些模型(或何时使用)。

视图看起来很明显,因为它模拟了大多数 JS 开发人员熟悉的典型“监听事件并做某事”方法。

我构建了一个简单的待办事项列表应用程序,到目前为止还没有看到需要 model 方面,所以我很好奇是否有人可以给我一些关于如何将它应用到这个应用程序的见解,或者如果如果我处理更复杂的数据,它就会发挥作用。

这是 JS:

Todos = (function(){

    var TodoModel = Backbone.Model.extend({

      defaults: {
          content: null
      }

    });

    var TodoView = Backbone.View.extend({

      el: $('#todos'),
      newitem: $('#new-item input'),
      noitems: $('#no-items'),

      initialize: function(){
        this.el = $(this.el);
      },

      events: {
        'submit #new-item': 'addItem',
        'click .remove-item': 'removeItem'
      },

      template: $('#item-template').html(),

      addItem: function(e) {
        e.preventDefault();
        this.noitems.remove();
        var templ = _.template(this.template);
        this.el.append(templ({content: this.newitem.val()}));
        this.newitem.val('').focus();
        return this;
      },

      removeItem: function(e){
        $(e.target).parent('.item-wrap').remove();
      }

  });

  self = {};
  self.start = function(){
    new TodoView();
  };
  return self;

});

$(function(){

    new Todos(jQuery).start();

});

这里运行的是:http://sandbox.fluidbyte.org/bb-todo

【问题讨论】:

    标签: javascript backbone.js model


    【解决方案1】:

    ModelCollection 在您必须持久对服务器进行更改时需要。

    例子:

    var todo = new TodoModel();
    

    创建一个新模型。当您必须保存保存更改时,请调用

    todo.save();
    

    您还可以将成功和错误回调传递给 save 。 Save 是 jQuery 提供的 ajax 函数的封装。

    如何在您的应用中使用模型。

    为你的模型添加一个 url 字段

    var TodoModel = Backbone.Model.extend({
    
      defaults: {
          content: null
      },
      url: {
          "http://localhost";  
      }
    
    });
    

    创建模型并保存。

    addItem: function(e) {
            e.preventDefault();
            this.noitems.remove();
            var templ = _.template(this.template);
            this.el.append(templ({content: this.newitem.val()}));
            this.newitem.val('').focus();
            var todo = new TodoModel({'content':this.newitem.val()});
            todo.save();
            return this;
          },
    

    确保您的服务器正在运行并且设置的 url 设置正确。

    学习资源:

    • 查看 Backbone 的 annotated 源代码以获得出色的 解释事情是如何在幕后发生的。
    • This Quora question 有很多优秀资源和示例应用的链接。

    【讨论】:

    • 好吧,这似乎合乎逻辑。因此代码将使用模型结构创建待办事项,然后将其传递给 url。很简单。
    【解决方案2】:

    如果您想在服务器端保存任何内容,该模型将非常有用。 Backbone 的模型是围绕 RESTful 端点构建的。因此,例如,如果您将 URL 根设置为 lists,然后将列表信息存储在模型中,则模型 savefetch 方法将允许您在 @ 处保存/接收描述模式到/从服务器的 JSON 987654326@ 端点。即:

       ToDoListModel = Backbone.model.extend( {
             urlRoot : "lists/" } );
    
       // Once saved, lives at lists/5
       list = new ToDoListModel({id: 5, list: ["Take out trash", "Feed Dog"] });
       list.save();
    

    因此,您可以使用它与通过 RESTful 接口保留在服务器上的数据进行交互。更多信息请参见this tutorial

    【讨论】:

    • 我正在考虑使用localStorage 作为维护数据的机制,这对模型来说是一个很好的用例吗?
    • Backbone 本身不支持本地存储,但是有一些插件可以支持,例如:github.com/jeromegn/Backbone.localStorage
    • 是的,这就是我打算使用的。那么,将设置/获取 LocalStorage 的命令保留在视图中,或者将其放入模型中是否有意义?
    【解决方案3】:

    我不同意 model 仅用于持久更改的想法(我在这里包括 LocalStorage,而不仅仅是服务器)。

    很高兴有模型和集合的表示,这样你就可以使用对象而不仅仅是视图。在您的示例中,您只是在页面中添加和删除 div(html),这是您可以使用 jQuery 通常执行的操作。每次执行“添加”时创建 Model 并将其添加到 Collection 并在清除时删除它会允许您做一些不错的事情,例如排序(按字母顺序)或过滤(如果您想实现“完成”待办事项的概念)。

    在你的代码中,例如:

    var TodoModel = Backbone.Model.extend({
        defaults: {
            content: null
            complete: false
        }
    });
    
    var Todos = Backbone.Collection.extend({
        model: TodoModel
    })
    

    在视图中(无关代码被跳过):

    // snip....
    addItem: function(e) {
        e.preventDefault();
        this.noitems.remove();
        var templ = _.template(this.template);
        var newTodo = new TodoModel({ content: this.newitem.val() });
        this.collection.add(newTodo); // you get the collection property from free from the initializer in Backbone
        this.el.append(templ({model: newTodo})); // change the template here of course to use model
        this.newitem.val('').focus();
        return this;
    },
    

    像这样初始化:

    self.start = function(){
        new TodoView(new Todos());
    };
    

    现在你有了一个支持集合,你可以做各种各样的事情,比如过滤。假设您有一个用于过滤已完成待办事项的按钮,您可以挂钩此处理程序:

    _filterDone: function (ev) {
        filtered = this.collection.where({ complete: true });
        this.el.html(''); // empty the collection container, I used "el" but you know where you are rendering your todos
        _.each(filtered, function (todo) {
            this.el.append(templ({model: todo})); // it's as easy as that! :)
        });
    }
    

    请注意,如果您的事件与内部视图挂钩,那么清空容器可能不是最好的事情,但作为初学者,这可以正常工作。

    您可能需要一个钩子来设置待办事项。创建一个按钮或复选框,也许还有这样的函数:

    _setDone: function (ev) {
        // you will need to scope properly or "this" here will refer to the element clicked!
        todo = this.collection.get($(ev.currentTarget).attr('todo_id')); // if you had the accuracy to put the id of the todo somewhere within the template
        todo.set('complete', true);
        // some code here to re-render the list
        // or remove the todo single view and re-render it
        // in the simplest for just redrawr everything
        this.el.html('');
        _.each(this.collection, function (todo) {
            this.el.append(templ({model: todo}));
        });
    }
    

    如果没有模型和集合,上面的代码就不会那么简单了,你可以看到它与服务器没有任何关系。

    【讨论】:

    • 感谢您提供详细信息!我从回复中得到的是使用上有一定的灵活性——但最佳实践是在我需要处理 DOM 操作之外的数据时使用模型。
    • 正是我的观点! :) 我想添加答案,因为其他答案都集中在服务器端同步上,这只是充分使用模型和集合的优点之一。
    猜你喜欢
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 2018-02-25
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    相关资源
    最近更新 更多