在主干应用中,什么是模型、视图和集合的工作

In a Backbone app what is work of model, views and collections by convention

本文关键字:视图 集合 工作 模型 应用 什么      更新时间:2023-09-26

我现在正在使用backbonejs mvc javascript库开发一个非常简单的应用程序。为了展示它有多简单这里是html

示例Html

<div class="container">
    <div>
        <label>
            Name:
            <input id="txtName" type="text" title="Type your name please" /></label>
        <button id="btnSubmit" type="button" value="Submit">
            Submit</button>
    </div>
    <div id="names">
    </div>
</div>

操作

这是我想让应用程序做的。

  1. 用户输入一个名称(或一些字母数字字符串)并点击提交

  2. 验证后的值(我想是他们称之为模型)将被发送到restful service

  3. 服务将返回相同的字符串以及数据库保存操作的状态。

我现在很困惑,点击事件将在哪里处理(它在模型中吗?),之后应该在哪里调用渲染方法?(是否在视图中)。下面你会发现我到现在为止管理的脚本

Model.js

//store a global reference to model
    window["model"] = Backbone.Model.extend({
        defaults: { name: "Type your name"
        },
        validate: function () {
        }
    });

View.js

//store a global reference to view
window["view"] = Backbone.View.extend({});

nothing in the view to say:

Application.js

//when every thing is ready kick of the application
$(document).ready(function () {

    var modelInstance = new model();

});
  1. 所以我在application.js或model.js中添加click event到按钮,这是惯例/最佳实践?

  2. 我是否有可能将从服务返回的名称集合呈现为#names,并将数据库插入状态呈现为容器上方某处的另一个div ?视图能同时呈现两个视图吗?

所以,这里有一个免责声明:如果这是你的应用程序所做的一切,那么Backbone是太多的仪式。当应用程序变得更复杂,有更多的活动部件时,Backbone变得非常惊人。

话虽如此,我已经创建了一个jsFiddle来强调如何使用Backbone来做你想做的事情:http://jsfiddle.net/BrianGenisio/CZwnk/4/

基本上,您有一个Person模型和一个People集合来保存Person模型。然后有三个视图:NewPersonView,它是输入数据的表单,负责向People集合添加新项。然后您有一个PeopleView视图,它负责显示People集合,它将监视集合并显示任何添加的内容。最后是PersonView,它负责显示单个Person模型。

当所有这些组合在一起时,它看起来有点像这样:

HTML:

<script id="new_person_template" type="text/template">    
    <label>
        Name:
        <input id="txtName" type="text" title="Type your name please" />
    </label>
    <button id="btnSubmit" type="button" value="Submit">Submit</button>
</script>
<script id="person_template" type="text/template">    
    Hello, my name is <%= name %>
</script>
<div id="container">
</div>
JavaScript

window.app = {};
window.app.Person = Backbone.Model.extend({
    defaults: { name: "Type your name" },
    validate: function () { }
});
window.app.People = Backbone.Collection.extend({
    model: window.app.Person
});
window.app.NewPersonView = Backbone.View.extend({
    template: _.template($("#new_person_template").html()),
    initialize: function () {
        _.bindAll(this, 'submit');
    },
    events:
    {
        "click #btnSubmit": "submit"
    },
    render: function () {
        $(this.el).html(this.template());
        return this;
    },
    submit: function (x, y, z) {
        // If you want this to go up to the server and sync, do this instead:
        // this.model.create({name: $("#txtName").val()});
        // but since we don't really have a server right now, we'll just create and add
        var person = new window.app.Person({name: $("#txtName").val()});
        this.model.add(person);
    }
});
window.app.PersonView = Backbone.View.extend({
    tagname: "li",
    template: _.template($("#person_template").html()),
    render: function() {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    }
});
window.app.PeopleView = Backbone.View.extend({
    tagName: "ul",
    initialize: function() {
        _.bindAll(this, "render", "renderPerson");
        this.model.bind("add", this.renderPerson);
    },
    render: function() {
       console.log("rendering");
       this.model.each(this.renderPerson);
       return this;
    },
    renderPerson: function(person) {
        var personView = new window.app.PersonView({model: person});
        $(this.el).append(personView.render().el);
    }
});

$(document).ready(function () {
    var people = new window.app.People();
    var newPersonView = new window.app.NewPersonView({model: people});
    var peopleView = new window.app.PeopleView({model: people});
    $("#container").html(newPersonView.render().el);
    $("#container").append(peopleView.render().el);
});

我将在视图中执行点击在我看来,你需要2个视图,1个是appview,包含整个应用另一个只是您在列表中呈现的每个用户模型的视图。

这是你的用户模型

var User = Backbone.Model.extend({
  defaults: {
    id: 0,
    name: 'no-name'
  }
});

这是您的收藏

var Users = Backbone.Collection.extend({
  model: User,
  create : function(model, options) {
    var coll = this;
    options || (options = {});
    if (!(model instanceof Backbone.Model)) {
      model = new this.model(model, {collection: coll});
    } else {
      model.collection = coll;
    }
    var success = function(savedModel, resp) {
      coll.add(savedModel);
      if (options.success) options.success(nextModel, resp);
      // fire success event
      coll.trigger("savesuccess", savedModel);
    };
    var error = function(resp) {
      if(options.error) options.error(resp);
      // fire error event
      coll.trigger("saveerror");
    }
    return model.save(null, {success : success, error : error});
  }
});

这是一个可能的用户视图

var UserRow = Backbone.View.extend({
  tagName: "li",
  initialize: function(){
    _.bindAll(this, 'render');
    this.model.bind('change', this.render);
  },
  className: "user",
  render: function() {
    var user = this.model;
    $(this.el).html(user.get('name'));
    return this;
  }
});

这是你的appView

var AppView = Backbone.View.extend({
  el: 'body',
  events: {
    'click button#btnSubmit': 'addUser'
  },
  initialize: function(){
    this.collection = new Users();
    this.collection.bind('add', this.appendUser);
    this.collection.bind('savesuccess', this.saveSuccess);
    this.collection.bind('saveerror', this.saveError);
    this.counter = 0;
    this.render();
  },
  addUser: function(){
    this.counter++;
    var user = new User();
    user.set({
      id: user.get('id') + this.counter,
      name: $('#txtName', this.el).val()
    });
    this.collection.add(user);
  },
  appendUser: function(user){
    var userRow = new UserRow({
      model: user
    });
    $('ul#names', this.el).append(userRow.render().el);
  },
  saveSuccess: function(user){
    alert('successfully saved, you can append something to the AppView DOM to show that saving was successful ...');
  },
  saveError: function(){
    alert('failed to save, you can append something to the AppView Dom to show that saving failed, or remove the item again ...');
  }
});

这里是初始化的

var App = new AppView();

如您所见,在将项目保存到数据库中之后,并不会呈现项目本身,而是将其添加到集合中,appView绑定到集合的add事件并将新用户附加到列表中。

CRUD服务器连接自动工作,因为在集合上使用了create函数。

这里的想法是,你不需要使用骨干事件,从你的集合中触发一个成功保存或错误保存的事件,并让任何视图绑定到该事件,以便在保存成功或失败时在屏幕上发生一些事情。