如何向模板显示集合?

时间:2012-08-16 09:49:14

标签: backbone.js

我一直在尝试将集合中的数据显示到模板中。在我的休息控制台上,我可以看到该集合已填充;但我无法在我的申请中这样做。代码如下: 在视图中,渲染类似于:

  render : function() {
                var template = _.template(tpl,{
                       CollectionForTemplate: this.Collection.toJSON(),
                this.el.html(template);

                },

在视图中,调用fetch的函数如下:

  loadTariffGrids: function(){
                       //fetch done here
                          if (Collection.length > 0) {
                                _.each(Collection, function(Model) {
                                       JSON.stringify(Model);
                           alert(JSON.stringify(Model));
                                }, this);
                          };
                          this.render;
                       }});


             },

最后,模板是:

                       <span>
                       <%  _.each(CollectionForTemplate, function(model) { %>
                       </span>      
                       <td><%= model.cost %></td>

                        <%     }); %>

我哪里错了?

2 个答案:

答案 0 :(得分:0)

在渲染中,只需使用:

CollectionForTemplate: this.Collection;

修改视图,如下所示:

var self = this;
//fetch done here
if (Collection.length > 0) {
                            _.each(Collection, function(Model) {
                                   JSON.stringify(Model);
                            }, this);
};
self.Collection = Collection;
self.render;

我认为您传递给模板的集合没有得到实例化。因此,在控制传递到fetch函数之前,我使用self来存储引用。我知道我的解释不好;我希望有更有经验的人能为您提供更好的解释。希望这有帮助

答案 1 :(得分:0)

好的@Amateur让我们试着正确地解决你的需求。

注意:所有代码都已在 中编写,不要指望它只是开箱即用,将其作为灵感来使用。

首先在你的模板中使用程序逻辑并不是一个好主意,这只是一个设计决定,我不想在这里看起来很学术,但我想如果你也是如此灵活,你可以完成一个非常难以维护的代码。

因此,我们的想法是制作数据,以便模板不做任何决策/计算。如果您需要在模板中使用循环,请使用子模板。

我从您的代码示例中了解到,您有一个这样的集合:

[
  {
    "id": "1",
    "cost": 100,
    "name": "Amateur"
  },

  {
    "id": "2",
    "cost": 200,
    "name": "Other name"
  },

  {
    "id": "3",
    "cost": 300,
    "name": "Other name again"
  },
]

你想要渲染这样的东西:

<table>
  <tr>
    <td>Name</td>
    <td>Cost</td>
  </tr>

  <tr>
    <td>Amateur</td>
    <td>100</td>
  </tr>

  <tr>
    <td>Other name</td>
    <td>200</td>
  </tr>

  <tr>
    <td>Other name again</td>
    <td>300</td>
  </tr>
</table>

正如我在您发送的另一个(重复)问题中读到的那样,您还希望仅cost呈现name == "Amateur",如下所示:

<table>
  <tr>
    <td>Name</td>
    <td>Cost</td>
  </tr>

  <tr>
    <td>Amateur</td>
    <td>100</td>
  </tr>

  <tr>
    <td>Other name</td>
    <td>--</td>
  </tr>

  <tr>
    <td>Other name again</td>
    <td>--</td>
  </tr>
</table>

Iteraction

对于迭代,我们将使用子模板解决它。

主模板:

<script type="text/template" id="template-elements">
  <table>
    <tr>
      <td>Name</td>
      <td>Cost</td>
    </tr>
  </table>
</script>

子模板

<script type="text/template" id="template-element">
  <tr>
    <td><%= name %></td>
    <td><%= cost %></td>
  </tr>
</script>

为了使其更加优雅,我们还可以为View使用Collection,为每个SubView使用Model

var MyModel = Backbone.Model.extend();
var MyCollection = Backbone.Collection.extend({
  model: MyModel
});

var MyModelView = Backbone.View.extend({
  template: _.template( $("#template-element").html() ),

  render: function(){
    this.$el.html( this.template( this.model.toJSON() ) );

    return this;
  }
});

var MyCollectionView = Backbone.View.extend({
  template: _.template( $("#template-elements").html() ),

  render: function(){
    this.$el.html( this.template() );

    this.collection.each( function( model ){
      var view = new MyModelView({ model: model });
      this.$el.find( "table" ).append( view.render().el );
    });

    return this;
  }
});

装修

我们已经解决了迭代问题,现在我们将实现在Model.cost时隐藏Model.name != "Amateur"的逻辑。

让我们实现一个方法,该方法返回已为模板准备的Model的属性:

var MyModel = Backbone.Model.extend({
  toJSONCooked: function(){
    var json = this.toJSON();

    if( this.get( "name" ) != "Amateur" ) {
      json.cost = "--";
    }

    return json;
  }
});

我们可以使用此方法提供模板

var MyModelView = Backbone.View.extend({
  template: _.template( $("#template-element").html() ),

  render: function(){
    this.$el.html( this.template( this.model.toJSONCooked() ) );

    return this;
  }
});