2014-12-12 3 views
2

2 개의 백본보기가 있습니다. 하나의 뷰 (AppView)는 전체 컬렉션을 나타내며 컬렉션을 가져 오면 컬렉션을 파싱하고 컬렉션의 각 모델에 대한 개별 모델 뷰를 생성합니다.백본 템플릿 안의 DOM 요소가 이벤트에 응답하지 않습니다.

내가 겪고있는 한 가지 문제는 모델보기가 생성 될 때 더 이상 모델보기의 한 방법 인 내 click 이벤트에 응답하지 않는 것입니다. 모델보기에서 tagNameel으로 바꿀 경우 이벤트가 실행될 수 있지만 개별 모델 대신 컬렉션의 모든 단일 모델에 대해 실행됩니다.

로드 할 때 템플리트에서 벗어나는 이벤트와 관련이 있다고 생각하지만 다시 묶는 방법을 알아 내거나 템플릿을 풀지 않고 템플릿을 생성하는 방법을 찾을 수 없습니다.

// INDIVIDUAL ITEMS WITHIN THE VIEW 
ModelView = Backbone.View.extend({ 
// el: '#item-block', // click event shows an action for all 20 models within the collection 
tagName: '.item-wrapper', // click event not heard 
template: _.template($('#template').html()), 
events: { 
    'click.details': 'fireModel', // .details is a div inside of the template 
}, 
initialize: function() { 

    // _.bindAll(this, 'render', 'fireModel'); 
    this.render(); 

}, 
render: function() { 

    var holder = $('#item-block'); 

    if(this.model.attributes.caption == null) { 
     var cloned = _.clone(this.model.get('caption')); 

     cloned = {}; 
     cloned.text = ''; 

     this.model.set('caption', cloned); 
    } 

    holder.append(this.template(this.model.toJSON())); 

    // this.delegateEvents() 

    // return this; 

}, 
fireModel: function(e) { 

    console.log('clicked'); 

}, 
}); 


// COLLECTION GENERATES INDIVIDUAL MODEL VIEW 
AppView = Backbone.View.extend({ 
el: '#social', 
events: { 
    'click #load-more': 'fetchCollection' 
}, 
initialize: function() { 
    this.collection = new MyCollection(); 

    this.collection.on('sync', this.render, this); 

    this.collection.fetchData(); 
}, 
render: function() { 

    for (var i = 0; i < this.collection.cache.models.length; i ++) { 
     modelView = new ModelView({model: this.collection.cache.models[i]}); 
    } 

}, 
fetchCollection: function() { 
    this.collection.fetchData(); 
}, 

}); 

// CREATE NEW COLLECTION 
app = new AppView 

여기에 어쩌면 당신은 이벤트와 선택 사이에 공백을 삽입해야 템플릿

<section id="social"> 

<div id="item-block"> 
</div> 

<div id="load-more">Load More</div> 

</section> 

<script type="text/template" id="template"> 

<div class="item-wrapper"> 
    <div class="details"> 
     <span class="caption"><%= caption.text %></span> 
    </div> 
    <div class="image"> 
     <img src="<%= images.standard_resolution.url %>" data-id="<%= id %>"> 
    </div> 
</div> 

</script> 

<!-- JS LIBS AND BACKBONE SCRIPTS HERE --> 
+0

템플릿 파일을 추가 할 수 있습니까 (HTML)? –

+0

예, 게시글을 업데이트했습니다. – user2989731

+0

''click.details ''대신''click .details ''라고 말하면 안됩니까? 그리고 왜 캡션을 복제 한 다음 빈 개체를 즉시 복제본에 할당합니까? –

답변

1

을 시도 :

먼저

, 나는 Backbone.ViewtagName 속성은 HTML 요소 (의 이름이어야 언급 할 div, ul .. .., 기본적으로 div입니다).

두 번째, 모델보기 (childView)를 모델보기에서 appView에 연결합니다. 그것은 더 나은 방식으로 구현 될 수 있습니다. 해당 로직을 appView (parentView)로 이동하십시오.

세번째for 루프 대신 Underscore.js의 each 메서드를 사용하십시오.

documentFragment를 사용하여 childView를 캐시하고 한 번에 하나씩 추가 (성능 최적화)합니다.

그리고 마지막 모습이어야합니다 : 그것은 parentView에 새로운 itemViews을 추가합니다 언제든지 수집의 sync 이벤트가 발생 이런 식으로

,

ModelView = Backbone.View.extend({ 
    template: _.template($('#template').html()), 
    attributes: { 
     'class': 'item-wrapper' 
    }, 
    events: { 
     'click .details': 'fireModel', // .details is a div inside of the template 
    }, 
    initialize: function() { 
     this.render(); 
    }, 
    render: function() { 
     this.$el.html(this.template(this.model.toJSON())); 
     return this; 
    }, 
    fireModel: function(e) { 
     console.log('clicked'); 
    }, 
}); 


// COLLECTION GENERATES INDIVIDUAL MODEL VIEW 
AppView = Backbone.View.extend({ 
el: '#social', 
events: { 
    'click #load-more': 'fetchCollection' 
}, 
initialize: function() { 
    this.collection = new MyCollection(); 
    this.collection.on('sync', this.render, this); 
    this.collection.fetchData(); 
}, 
render: function() { 
    var buffer = document.createDocumentFragment(); 
    this.collection.each(function(model){ 
     if(model.attributes.caption == null) { 
      // do your checks here 
     } 
     var itemView = new ModelView({model: model}); 
     buffer.appendChild(itemView.render().el); // adding it to buffer 
    }); 

    this.$el.append(buffer); // appending all at once 
} 
}); 

// CREATE NEW COLLECTION 
app = new AppView(); 

업데이트, 그래서 검사를 추가해야합니다 그곳에.

+0

감사합니다! DocumentFragment에 좋은 참고. 그러나'this.buffer'가'buffer'로 호출되어야하므로 하단을 업데이트 할 수 있습니다. – user2989731

+0

그것이 도움이 되었기 때문에 기쁩니다. 나는 그것을 지금 새롭게 할 것이다. –

+0

@ user2989731 답변이 도움이되고 문제를 해결할 수 있다면 받아 들일 수 있습니다. –

0

입니다.

이 몇 가지주의 할

'click .details': 'fireModel' 
관련 문제