在 Backbone 应用程序中,按惯例模型、视图和集合的工作原理是什么

发布于 2024-12-08 06:13:17 字数 1487 浏览 1 评论 0原文

我现在正在使用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服务。

  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({});

视图中没有任何内容:(

Application.js

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


    var modelInstance = new model();


});
  1. 所以我将单击事件添加到 application.js 或 model.js 中的按钮。这是约定/最佳实践?

  2. 我可以渲染吗?从服务返回的名称集合到 #names 中并且数据库插入到容器上方的另一个 div 的状态?视图可以渲染两个视图吗?

I am right now developing a dead simple application using backbonejs mvc javascript library.Just to show how simple it is here is the html

Sample 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>

Operation

Here's all i want the application to do.

  1. User Types a name(or some alphanumeric string) and clicks submit.

  2. The value(which is what they call model i suppose) after validation will be sent to restful service.

  3. Service will return the same string along with status of database save operation.

I am now confused as to where the click event will handled(is it in the model?), after that where should the render method be called?(is it in views). Below you will find the script i had managed up until now

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. so do i add click event to the button in application.js or model.js.which is the convention/best practice?

  2. Will it be possible for me to render the names collection returned from service into #names and status of the database insertion into another div somewhere up above the container? Can the view render both views?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦行七里 2024-12-15 06:13:17

因此,这里有一个免责声明:如果这就是您的应用程序所做的全部事情,那么 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);
});

So, here is a disclaimer: If this is all your app is doing, then Backbone is way too much ceremony. When the app gets more complex with more moving parts, Backbone becomes pretty amazing.

That being said, I have created a jsFiddle to highlight how you might use Backbone for what you want to do: http://jsfiddle.net/BrianGenisio/CZwnk/4/

Basically, you have a Person model and a People collection to hold the Person models. You then have three views: NewPersonView which is the form for entering your data, which is responsible for adding new items to the People collection. Then you have a PeopleView view which is responsible for showing People collection, which will watch the collection and show any additions. Finally, is the PersonView which is responsible for showing an individual Person model.

When it all comes together, it looks a little something like this:

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);
});
热血少△年 2024-12-15 06:13:17

我会在视图中单击
在我看来,你需要 2 个视图,1 个是保存整个应用程序的应用程序视图
另一个只是您在列表中呈现的每个用户模型的视图。

这是你的用户模型,

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 服务器连接会自动工作。

这里的想法是,您不需要使用主干事件,从集合成功保存或错误保存中触发事件,并让任何视图绑定到该事件以使屏幕上发生某些事情保存是否成功。

i would do the click in the view
you would need 2 views in my eyes, 1 is an appview that holds your entire app
the other is just a view for each usermodel you render out in your list .

here is your user model

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

here is your collection

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

so here is a possible user view

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

});

here is your 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 ...');
  }
});

here you initialize it all

var App = new AppView();

as you can see, rendering the items itself does not happen after saving it in the database, it is added to the collection, the appView binds to the add event of the collection and appends the new user to your list.

the CRUD server connection works automatically, due to using the create function on the collection.

the idea here is that you don't need to user backbone events, trigger an event from your collections successful save or error save, and let any view bind to that event to make something happen on the screen when save was a success or not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文