2012-04-21 23 views
13

Estoy tratando de representar una tabla html usando el motor de plantilla de guión bajo. En primer lugar tengo la respuesta JSON desde el servidor de estaRenderizar tabla html con motor de plantilla de guión bajo usando un modelo complejo de troncal

{ 
    CurrentModel: { 
     Heading: "Home", 
     Id: "pages/193", 
     Metadata: { 
      Name: "Home", 
      Title: null, 
      Keywords: null, 
      Description: null, 
      DisplayInMenu: true, 
      Published: "/Date(1334499539404)/", 
      Changed: "/Date(1334499539404)/", 
      ChangedBy: "Marcus", 
      IsPublished: true, 
      IsDeleted: false, 
      Slug: null, 
      Url: null, 
      SortOrder: 0 
     }, 
     Parent: null, 
     Children: [ 
      "pages/226", 
      "pages/257" 
     ] 
}, 
    Children: [ 
     { 
      Heading: "Foo", 
      MainBody: null, 
      Id: "pages/226", 
      Metadata: { 
       Name: "I'm an article", 
       Title: null, 
       Keywords: null, 
       Description: null, 
       DisplayInMenu: true, 
       Published: "/Date(1334511318838)/", 
       Changed: "/Date(1334511318838)/", 
       ChangedBy: "Marcus", 
       IsPublished: true, 
       IsDeleted: false, 
       Slug: "i-m-an-article", 
       Url: "i-m-an-article", 
       SortOrder: 1 
      }, 
      Parent: {}, 
      Children: [ ] 
     }, 
     { 
      Heading: "Bar", 
      MainBody: null, 
      Id: "pages/257", 
      Metadata: { 
       Name: "Foo", 
       Title: null, 
       Keywords: null, 
       Description: null, 
       DisplayInMenu: true, 
       Published: "/Date(1334953500167)/", 
       Changed: "/Date(1334953500167)/", 
       ChangedBy: "Marcus", 
       IsPublished: true, 
       IsDeleted: false, 
       Slug: "foo", 
       Url: "foo", 
       SortOrder: 2 
      }, 
      Parent: {}, 
      Children: [ ] 
     } 
    ] 
} 

El resultado HTML que estoy buscando es más o menos como este donde i print algunos de los datos de la CurrentModel y la iterar a través de la propiedad de los niños, preferiblemente cada tr en the tbody debería ser una vista usando backbone.js para que pueda conectar algunos eventos para esta fila en particular.

<table> 
    <caption><%= CurrentModel.Metadata.Name %></caption> 
    <thead> 
     <tr> 
      <th><span>Page name</span></th>     
      <th><span>Slug</span></th> 
      <th><span>Published</span></th> 
      <th><span>Changed</span></th> 
     </tr> 
    </thead> 
    <tbody> 
     <% _(Children).each(function(page) { %> 
      <tr> 
       <td><%= page.Metadata.Name %></td> 
       <td><%= page.Metadata.Slug %></td> 
       <td><%= page.Metadata.IsPublished %></td> 
       <td><%= page.Metadata.Changed %></td> 
      </tr>      
     <% }); %> 
    </tbody> 
</table> 

Ahora, mi pregunta es ¿cómo deben mis puntos de vista y la columna vertebral modelos parecerse o no es destinado a ser utilizado de esta manera? El código de javasscript a continuación funciona y representa un tr para cada niño si la respuesta del servidor es solo una colección de página, entiendo mucho, pero no sé cómo modificar el código para que pueda tomar un modelo complejo y luego representar partes de ese modelo en una o tal vez dos vistas javascript?

En mis application.js tengo este código

pages: function() { 
    this.pageList = new PageCollection(); 
    this.pageListView = new PageListView({ model: this.pageList }); 
    this.pageList.fetch(); 
} 

donde PageCollection se parece a esto

var PageCollection = Backbone.Collection.extend({ 
    url: '/pages', 
    model: Page 
}); 

la clase modelo como este

Page = Backbone.Model.extend({ 
    metadata: { 
     name: null, 
     title: null, 
     keywords: null, 
     description: null, 
     displayInMenu: null, 
     published: null, 
     changed: null, 
     changedBy: null, 
     isPublished: null, 
     isDeleted: null, 
     slug: null, 
     url: null, 
     sortOrder: null 
    }, 
    parent: {}, 
    children: [], 
    ancestors: null, 
    initialize: function() { } 
}); 

la PageListView

PageListView = Backbone.View.extend({ 
    tagName: 'table', 
    initialize: function() { 
     this.model.bind("reset", this.render, this); 
    }, 
    render: function (eventName) { 
     _.each(this.model.models, function (page) { 
      $(this.el).append(new PageListItemView({ model: page }).render().el); 
     }, this); 
     return this; 
    } 
}); 

y por fin el PageListItemView

PageListItemView = Backbone.View.extend({ 
    tagName: "tr", 
    template: _.template($('#tpl-page-list-item').html()), 
    events: { 
     "click td input[type=checkbox]": "publish" 
    }, 
    render: function (eventName) { 
     $(this.el).html(this.template(this.model.toJSON())); 
     return this; 
    }, 
    publish: function (event) { 
     alert('Publish'); 
    } 
}); 
+0

¿No es posible hacer algo como esto? – Marcus

Respuesta

14

En primer lugar, me gustaría analizar los datos en la colección para obtener una lista de las páginas y tal vez agarrar la definición CurrentModel:

var PageCollection = Backbone.Collection.extend({ 
    url: '/pages', 
    model: Page, 

    parse: function(response) { 
     this.CurrentModel=new Page(response.CurrentModel); 
     return response.Children; 
    } 
}); 

Luego, con la plantilla de fila configurada como

<script id="tpl-page-list-item" type="text/template"> 
    <tr> 
     <td><%= Metadata.Name %></td> 
     <td><%= Metadata.Slug %></td> 
     <td><%= Metadata.IsPublished %></td> 
     <td><%= Metadata.Changed %></td> 
     <td><input type='checkbox' /></td> 
    </tr> 
</script> 

puede definir sus vistas más o menos como usted ellos tenían

var PageListItemView = Backbone.View.extend({ 
    template: _.template($('#tpl-page-list-item').html()), 
    events: { 
     "click input[type=checkbox]": "publish" 
    }, 
    render: function (eventName) { 
     var html=this.template(this.model.toJSON()); 
     this.setElement($(html)); 
     return this; 
    }, 
    publish: function() { 
     console.log(this.model.get("Metadata").Name); 
    } 
}); 

var PageListView = Backbone.View.extend({ 
    tagName: 'table', 
    initialize: function() { 
     this.collection.bind("reset", this.render, this); 
    }, 
    render: function (eventName) { 
     this.$el.empty(); 

     this.collection.each(function(page) { 
      var pageview=new PageListItemView({ model: page }); 
      var $tr=pageview.render().$el;   
      this.$el.append($tr); 
     },this); 

     return this; 
    } 
}); 

inicializar la colección y las vistas, ir a buscar los datos, y usted debe tener algo equivalente a este violín: http://jsfiddle.net/NtmB4/

var coll=new PageCollection(); 
var view=new PageListView({collection:coll}) 
$("body").append(view.render().el); 

coll.fetch(); 

Y un violín que corresponde a la plantilla completa http://jsfiddle.net/NtmB4/2/

+0

@Marcus ¿Esto respondería a tu pregunta? ¿O encontraste tu propio camino? – nikoshr

+0

¡Muchas gracias por esta respuesta perfecta! – Marcus

+0

¿Qué hay del thead? –

Cuestiones relacionadas