2012-04-26 2 views
10

테이블 뷰에서 렌더링하려는 모델 모음이 있습니다. 각 모델은 테이블의 단일 행으로 나타내야하며,이 행은 템플리트를 사용하여 생성되어야합니다. 해당 행 (예 : 클릭)에 이벤트 핸들러를 첨부 할 수 있어야하며, 이벤트가 발생할 때 해당 행과 관련된 모델에 대한 특정 정보를 알릴 수 있어야합니다.백본 테이블 뷰 소비 행 뷰 - 구조화 방법?

내가 한 일과 비슷한 일을하는 일반적인 방법은 각 행을 자체보기로 나누고 부모보기 (이 경우 테이블을 말함)를 사용하여 행보기를 사용하여 HTML을 생성하는 것입니다. 코드에 포함하십시오. 그러나 나는 이것이 템플릿과 어떻게 작동 하는지를 알 수 없다.

이 경우 dom 요소 (백본의 경우 this.el)에 대한 참조가 없으므로 RowView에만 이벤트를 첨부 할 수 없습니다. 단순히 문자열을 반환합니다. 최대 용량까지 템플릿을 사용하면서 원하는 것을 어떻게 얻을 수 있습니까?

질문은 특히 이벤트, 템플릿 또는 중첩 된보기를 사용하는 것이 아니라 이러한 종류의 출력을 얻기 위해 백본을 사용하는 올바른 방법에 관한 것입니다. (또한 fiddle)에

샘플 코드 :

/** View representing a table */ 
var TableView = Backbone.View.extend({ 
    tagName: 'table', 
    render: function() { 
     var rows = _.map(this.collection.models, function(p) { 
      return new RowView({model: p}).render();       
     }); 
     $('body').html(this.$el.html(rows.join(''))); 
    } 
}); 

/** View representing a row of that table */ 
var RowView = Backbone.View.extend({ 
    render: function() { 
     // imagine this is going through a template, but for now 
     // lets just return straight html. 
     return '<tr>' + 
       '<td>' + this.model.get('name') + '</td>' + 
       '<td>' + this.model.get('age') + '</td>' + 
       '</tr>'; 
    } 
}); 

var data = [ 
    {'name': 'Oli', 'age': 25}, 
    {'name': 'Sarah', 'age': 20}]; 

/** Collection of models to draw */ 
var peopleCollection = new Backbone.Collection(data); 
var tableView = new TableView({collection: peopleCollection}); 
tableView.render(); 

감사합니다!

답변

11

보기 계층 구조를 처리하는 한 가지 방법은 각보기가 자식을 렌더링하고이를 el에 추가하도록하는 것입니다. 이벤트는 모델/컬렉션에 따라 각보기에서 처리됩니다. 당신이 백본 보기를 적용 할 경우

el로 HTML을 주입함으로써 컨테이너 요소를 제어하려면, 당신은 setElement 방법

setElementview.setElement(element)

을 사용할 수 있습니다 다른 DOM 엘리먼트로 setElement를 사용하면 캐시 된 $ el 참조를 생성하고 뷰의 위임 된 이벤트 을 이전 요소에서 새로운 요소로 옮길 수 있습니다.

귀하의 예는

var rowTemplate=_.template("<tr>"+ 
    "<td class='name'><%= name %></td>"+ 
    "<td class='age'><%= age %></td>"+ 
    "</tr>"); 

/** View representing a table */ 
var TableView = Backbone.View.extend({ 
    tagName: 'table', 

    initialize : function() { 
     _.bindAll(this,'render','renderOne'); 
    }, 
    render: function() { 
     this.collection.each(this.renderOne); 
     return this; 
    }, 
    renderOne : function(model) { 
     var row=new RowView({model:model}); 
     this.$el.append(row.render().$el); 
     return this; 
    } 
}); 

/** View representing a row of that table */ 
var RowView = Backbone.View.extend({ 
    events: { 
     "click .age": function() {console.log(this.model.get("name"));} 
    }, 

    render: function() { 
     var html=rowTemplate(this.model.toJSON()); 
     this.setElement($(html)); 
     return this; 
    } 
}); 

var data = [ 
    {'name': 'Oli', 'age': 25}, 
    {'name': 'Sarah', 'age': 20}]; 

/** Collection of models to draw */ 
var peopleCollection = new Backbone.Collection(data); 
var tableView = new TableView({collection: peopleCollection}); 
$("body").append(tableView.render().$el); 

그리고 바이올린 http://jsfiddle.net/9avm6/5/

+0

로 다시 작성할 수'setElement' 내가 실종했던 부분이었다 - 감사합니다! –

+0

굉장합니다. 하나의 질문입니다 .bindAll 호출에 대해 자세히 설명해 주시겠습니까? 함수가 호출 될 때 'this'를 더 유용하게 만드는 것으로 알고 있지만 그 형식의 호출은 무엇을 의미합니까? 어떤 이벤트에 당신은 render와 renderOne을 바인딩하고 있습니까? renderOne을 왜 바인딩할까요? 정말 고마워! – Nicolas78

+0

@ Nicolas78 _.bindAll은 render와 renderOne에서'this'가 뷰가되고, 이벤트를 트리거 한 요소가 아니라는 것을 보증합니다. 여기서는별로 유용하지 않지만 바인딩은 설정되지 않지만 collection.reset에서 render를 호출하고 collection.add에서 renderOne을 호출 할 수 있습니다. 추가 – nikoshr