我什么时候需要backbone.js中的模型?

时间:2012-10-25 13:02:18

标签: javascript backbone.js model

我是Backbone.js的新手,并且从JS开发的“标准”模型中脱颖而出的人我对如何使用模型(或何时)不太了解。

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

我构建了一个简单的Todo列表应用程序,到目前为止还没有看到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

3 个答案:

答案 0 :(得分:3)

当您必须持久对服务器进行更改时,需要

ModelCollection

示例:

var todo = new TodoModel();

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

todo.save();

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

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

在模型中添加网址

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;
      },

确保您的服务器正在运行并设置网址设置正确。

学习资源:

  • 查看Backbone的annotated源代码 解释事情如何落后于幕后。
  • This Quora question包含许多优秀资源和示例应用的链接。

答案 1 :(得分:2)

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

   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

答案 2 :(得分:2)

我不同意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}));
    });
}

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