3

我是 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

4

3 回答 3

3

当您必须将更改持久保存到服务器时,需要模型集合。

例子:

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 的带注释的源代码,以很好地解释事情是如何在幕后落实到位的。
  • 这个 Quora 问题有很多很好的资源和示例应用程序的链接。
于 2012-10-25T13:25:07.060 回答
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 接口保留在服务器上的数据进行交互。有关更多信息,请参阅本教程

于 2012-10-25T13:20:11.373 回答
2

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

拥有模型和集合的表示是很好的,这样您就可以使用对象而不仅仅是视图。在您的示例中,您只是在页面中添加和删除 div(html),这是您可以使用 jQuery 通常执行的操作。Model每次执行“添加”时都创建并添加到 a中,并且可能在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}));
    });
}

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

于 2012-10-25T16:32:43.860 回答