Backbone.js的更新变得查看一个烂摊子 [英] Updating Backbone.js View becoming a mess

查看:106
本文介绍了Backbone.js的更新变得查看一个烂摊子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个模式:

MyModel = Backbone.Model.extend({
  defaults: {
    name: '',
    age: -1,
    height: '',
    description: ''
  }
});

和视图渲染模型的列表:

and a View to render the model as a list:

MyView  = Backbone.View.extend({
  tagName: 'ul',
  className: 'MyView',

  render() {
    var values = {
      name: this.model.get('name'),
      age: this.model.get('age'),
      height: this.model.get('height'),
      description: this.model.get('description')
    }

    var myTemplate = $('#MyView-Template').html();
    var templateWithValues = _.template(myTemplate , values);
  }
});

和经查看装入一个模板:

and a template loaded by the View:

<script type="text/template" id="MyView-Template">  
  <li class="name"><%= name %></li>
  <li class="age"><%= age %></li>
  <li class="name"><%= height%></li>
  <li class="name"><%= description%></li>
</script>

一切正常,虽然这是一个人为的例子,真正的code的模型中的许多,许多的属性。我遇到的问题是如何的处理更新模型。

创建具有用于每个场的适当的输入元件的HTML形式。表单建模并加载作为模板:

I create an HTML form which has an appropriate input element for each field. The form is modelled and loaded as a template:

<script type="text/template" id="MyEditView-Template">  
  <input type"text" value="<%= name %>" /> <br />
  <input type"text" value="<%= age%>" /> <br />
  <input type"text" value="<%= height%>" /> <br />
  <input type"text" value="<%= description%>" /> 
</script>

和加载到一个视图:

MyEditView  = Backbone.View.extend({
      tagName: 'form',
      className: 'MyEditView',

      render() {
        var values = {
          name: this.model.get('name'),
          age: this.model.get('age'),
          height: this.model.get('height'),
          description: this.model.get('description')
        }

        var myTemplate = $('#MyEditView-Template').html();
        var templateWithValues = _.template(myTemplate , values);
      }
    });

当用户保存的形式,新值在模型(为MyModel)来设置。不过,我不想再渲染整个原始视图,时间过久,有许多嵌套元素。我只是想更新其中有他们的价值在模型中修改HTML元素。

When the user saves the form, the new values are set in the model (MyModel). However I do not want to re-render the entire original view, it takes too long and has many nested elements. I only want to update the HTML elements which have had their value changed in the model.

问题是我怎么能优雅地链接模型的属性为HTML元素,让我可以做下面的一个已渲染视图

The problem is how can I elegantly link a model's attributes to HTML elements, so that I can do the following to an already rendered view:


  1. 迭代模型的属性。

  2. 确定哪个属性已被修改。

  3. 只有更新UI的修改的属性。

  4. 任何$ P $隐藏UI pviously渲染,这样应该不会再显示属性。

一个该属性名称映射到一个HTML元素串的那一刻我有一个JavaScript查找表(只是一个对象)相当丑陋的解决方案:

A the moment I have a rather ugly solution of a JavaScript lookup table (just an object) which maps an attribute name onto an HTML element string:

var AttributesMap = {
    name: {
        htmlRef: 'li.name',
        attributeName: 'name'
    },
    age: {
        htmlRef: 'li.age',
        attributeName: 'age'
    }
    ...
}

这感觉哈克并导致一些pretty臃肿code。

This feels hacky and has resulted in some pretty bloated code.

推荐答案

居然还有藏在你的后两个问题。你必须与模型的属性问题,你不知道,如果如何订阅模式变革的事件。幸运的是,这两种都是可能容易与Backbone.js的。更改您的视图code以下

there is actually two questions hidden in your post. You have problem with attributes of the model and you are not aware if how to subscribe to model change events. Luckily both of these are possible easily with backbone.js. Change your view code to below

render: function () {
    var model = this.model;
    $(this.el).empty().html(_.template(this.template, this.model.toJSON()))
    return this;
}

是定义容器的视图属性。 的toJSON()是,你可以在模型调用方法序列化格式,可以通过线路传输。

where el is property of the view that defines the container. toJSON() is a method you can invoke on the model to serialize it format that can be transferred over the wire.

意见都应该订阅其模型更改事件初始化功能或更多恰当地使用委派事件支持。当过一个模型属性更改了变更事件在该模式,您可以订阅喜欢的这里和下面的例子。

Views are supposed to subscribe to model change events in their initialize function or more aptly use the delegated event support. When ever a model attribute changes a change event is invoked on that model which you can subscribe to like here and example below.

window.ListView = Backbone.View.extend({
    initialize: function () {
        //pass model:your_model when creating instance
        this.model.on("change:name", this.updateName, this);
        this.model.on("change:age", this.changedAge, this);
    },
    render: function () {
        var model = this.model;
        $(this.el).empty().html(_.template(this.template, this.model.toJSON()))
        return this;
    },
    updateName: function () {
        alert("Models name has been changed");
    },
    changedAge: function () {
        alert("Models age has been changed");
    }
});

JsBin例如

http://jsbin.com/exuvum/2

这篇关于Backbone.js的更新变得查看一个烂摊子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆