2012-12-28 2 views
3

나는 나무의 범주가 있고 jQuery를 사용하는 대신 Backbone.js를 사용하여 렌더링을 수행하거나 서버 측에서 렌더링을 수행하고 싶습니다.Backbone.js에서 중첩 된 뷰를 렌더링하는 방법은 무엇입니까?

<li> 
    <select class="categories"> 
     <option value="">Select</option> 
    </select> 
    <input class="edit" type="button" value="Edit"> 
    <input class="add" type="button" value="Add"> 
</li> 

내가 내보기로 별도로 렌더링 태그 select : 나는 템플릿으로 설명 된 다음 브레이크 아웃 있습니다. select를 변경하면 서버에서 중첩 된 범주를 가져와 ul 태그로 묶은 위의 템플릿을 사용하여 li 태그에 추가해야합니다. 아우터 뷰에서 내부 뷰를 만들고 편집 및 추가시 클릭하여 이벤트를 수신합니다. 중첩 수준과 동일한 횟수의 화재이기 때문에 중첩 수준이 둘 이상인 마지막 이벤트에 문제가 있습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

var CategoriesInnerView = Backbone.View.extend({ 
     tagName:  'select', 
     initialize: function(){ 
      _.bindAll(this,'addOne','addAll'); 
      this.collection.bind('reset',this.addAll); 
     }, 
     addOne:  function(category){ 
      this.$el.append(new CategoryView({model:category}).render().el); 
     }, 
     addAll:  function(){ 
      this.collection.each(this.addOne); 
     }, 
     events:  { 
      'change':'changeSelected' 
     }, 
     changeSelected:function(){ 
      var children = new Categories(); 
      children.url = 'categories/' + this.$el.val(); 

      var childrenView = new CategoriesOuterView({collection:children}); 
      this.$el.parent().find('ul').remove(); 
      this.$el.parent().append(childrenView.render().el); 

      children.fetch(); 
     } 
    }); 

    var CategoriesOuterView = Backbone.View.extend({ 
     tagName: 'ul', 
     template: _.template($('#categories-template').html()), 
     initialize:function(){ 
      this.inner = new CategoriesInnerView({collection:this.collection}); 
     }, 
     render: function(){ 
      this.$el.html(this.template); 

      this.inner.setElement(this.$('select')).render(); 

      return this; 
     }, 
     events: { 
      'click .edit':'edit', 
      'click .add': 'add' 
     }, 
     edit: function(){ 
      this.renderForm(this.collection.get(this.inner.$el.val())); 
     }, 
     add: function(){ 
      this.renderForm(new Category()); 
     }, 
     renderForm:function(category){ 
      // some code to render the form 
     } 
    }); 
+0

"의 이벤트 전파를 중지하는 것입니다 데모에 대한 http://jsfiddle.net/PX2PL/보기 ", 백본에는 렌더링 기능이 내장되어 있지 않습니다. – Prinzhorn

+0

예, 알고 있습니다. 내가 틀렸어. –

답변

3

중첩 된 뷰를 설정할 때 이벤트가 DOM 트리 위로 올라가고 Backbone이 view.el 수준에서 DOM 이벤트를 처리한다는 사실을 고려해야합니다. 즉, 시나리오에서 중첩 된 노드는 이벤트를 계층 구조 위로 올리면 부모 노드에서 이벤트를 트리거합니다.

간단한 해결책이 콜백

var CategoriesOuterView = Backbone.View.extend({ 
    events: { 
     'click .edit':'edit', 
     'click .add': 'add' 
    }, 
    edit: function(e) { 
     e.stopPropagation(); 
     this.renderForm(this.collection.get(this.inner.$el.val())); 
    }, 
    add: function(e) { 
     e.stopPropagation(); 
     this.renderForm(new Category()); 
    } 
} 

그리고 Backbone.js 대신 jQuery를 사용하여 업데이트 된 데모 http://jsfiddle.net/PX2PL/1/

+0

답변을 주셔서 감사 드리며, 이미 같은 방식으로 해결했습니다. –

2

우리는 정말 코드의 일부가 제대로이 대답하는 것해야하지만 두 가지 중 하나가 일어나고있는 것처럼 소리 : 나는 외부 및 내부 전경과 함께 작동하는 방법을

아래의 코드는 보여줍니다

1) 같은 요소보기의 인스턴스를 여러 번

2) 이벤트 선택기는 너무 광범위

그러나 witho

실제로 당신의 견해 (관련 부분)를 보게되면 그 이상의 것을 말하기 어렵습니다. 이 같은이있을 때


접선 관련 사이드 참고 BTW

는 두 가지 기본 방법이 있습니다 당신이 취할 수

1) 당신은 서브를 만들려면 부모보기를 할 수 있습니다 하위보기에 이벤트 처리를 넣으십시오.

2) 부모보기에서 하위보기를 만들거나 (모든 HTML 자체를 만들 수 있음) 이벤트 처리를 할 수 있습니다.

# 1의 장점은 간단합니다. 이벤트 처리기는 this을 참조하여 관련보기를 참조 할 수 있습니다. 그러나 너무 많은 확장이 필요하다면 # 1에 문제가 있습니다. 각각의 이벤트 핸들러가있는 수백만 개의보기가 성능을 저하시킵니다.

성능이 중요하거나 더 중요 할 경우 단일 이벤트 연결 만 수행하기 때문에 # 2가 더 좋습니다. 그러나 제공된 이벤트 (즉, e.target 대 1 위 접근의 경우 this)를 기반으로 작업하는 요소를 파악해야하기 때문에 이벤트 처리기가 더 스마트 해져야합니다.

+0

가치가있는 점에 대해 4-5 단계의 중첩 수준을 가진 뷰가 있으며 경로 1은 항상 매우 간단하고 구현하기 쉽습니다. – asawyer

+0

이론 상으로는 얼마나 많은 중첩 수준에 관계없이 접근 # 1을 수행하면 구현이 매우 간단하고 쉽습니다. 접근법 # 2는 어렵지 않습니다 (# 1보다 열심히). 그러나 물론 (당신이 발견 한대로) 악마가 가장 확실하게 세부 사항에 있습니다. – machineghost

+0

위에 코드 스 니펫을 추가했습니다. 제발보십시오. –

관련 문제