2012-05-19 4 views
0

백본에서 첫 번째 응용 프로그램을 만들고 있는데 이벤트를 첨부하려고하는데 이상한 일이 생깁니다. 백본보기 이벤트가 모든보기에 도달했습니다.

는 지금까지이 코드를 가지고 :

//View for @girl, EDIT action 
GirlEditView = Backbone.View.extend({ 
    initialize: function(el, attr) { 
     this.variables = attr; 
     console.log(attr); 
     this.render(); 
    }, 
    render: function() { 
     var template = _.template($("#girl_edit").html(), this.variables); 
     $(this.el).html(template); 
     $("#edit_girl").modal('show'); 
    } 
}); 

//View for @girl 
GirlView = Backbone.View.extend({ 
    initialize: function(el, attr) { 
     this.variables = attr; 
     this.render(); 
    }, 
    render: function() { 
     var template = _.template($("#girl_template").html(), this.variables); 
     $(this.el).html($(this.el).html() + template); 
    }, 
    events: { 
     "click p.modify": "modify" 
    }, 
    modify: function() { 
     //calls to modify view 
     new GirlEditView({el : $("#edit_girl")}, this.variables); 
    } 
}); 


//One girl from the list 
Girl = Backbone.Model.extend({ 
    initialize: function() { 
     this.view = new GirlView({el : $("#content")}, this.attributes); 
    } 
}); 

//all the girls 
Girls = Backbone.Collection.extend({ 
    model: Girl, 
}); 




//do magic! 
$(document).ready(function() { 

    //Underscore template modification 
    _.templateSettings = { 
     escape : /\{\[([\s\S]+?)\]\}/g, 
     evaluate : /\{\[([\s\S]+?)\]\}/g, 
     interpolate : /\{\{([\s\S]+?)\}\}/g 
    } 

    //get initial data and fill the index 
    var list = []; 
    $.getJSON('girls.json', function(data) { 
     list = []; 
     $.each(data, function(key, val) { 
      list.push(new Girl(val)); 
     }); 

     var myGirls = new Girls(list); 
     console.log(myGirls.models); 
    }); 
}); 

당신이 볼 수 있듯이.

나는 모든 소녀를 저장하는 컬렉션을 사용하고 있으며 데이터는 루비의 REST API에서 제공됩니다.

각 소녀는 새 모델 인스턴스를 만들고 내부에 뷰 인스턴스를 첨부했습니다.

좋은 습관인지는 모르겠지만 더 좋은 방법이라고 생각하지 않습니다.

각보기는 고유 한 ID로 콘텐츠를 만듭니다. 여자 -1 여자 -2 그리고 계속해라.

이제 템플릿에 수정 버튼이 있습니다. 원래 독창적 인 아이디어는 onclick 이벤트를 공격하고 편집보기를 실행하여 렌더링되도록하는 것입니다.

예상대로 작동합니다.

지금까지입니다 proble :

이벤트가 트리거

, 모든 컬렉션 (여자) 편집보기가 아닌 렌더링 된 뷰를 "소유"사람을 해고.

제 질문은 내가 잘못하고있는 것입니다.

덕분에 모든 GirlViews이 같은 el을 사용하고 있기 때문에

답변

3

모든 편집 -보기는 올 많은 :

render: function() { 
    var template = _.template($("#girl_template").html(), this.variables); 
    $(this.el).html($(this.el).html() + template); 
} 
:

this.view = new GirlView({el : $("#content")}, this.attributes); 

을 한 다음 렌더링 더 HTML을 추가 할 수

백본 이벤트는보기의 el에서 delegate을 사용하여 바인딩됩니다. 따라서 여러 개의보기가 동일한 el을 공유하는 경우 동일한 DOM 요소에 여러 개의 delegate이 첨부되고 이벤트가 내재됩니다.

모델은보기를 소유하지 않으며,보기는 모델과 컬렉션을보고 이벤트에 응답합니다. 당신이 right in the documentation 볼 수 있습니다 :

생성자/초기화new View([options])

[...] 통과하는 경우, 직접보기로 첨부됩니다 몇 가지 특별한 옵션이 있습니다 : model, collection는, [...그 감싸보기를

var v = new View({ collection: c }) 

또는 당신은 모델, m를 만든 다음 생성 :]

일반적으로, 당신은 수집, c를 만든 다음 그것을 그 콜렉션을 전달하여 뷰를 생성 모델 :이 기본 데이터의 변경 등의 표시를 업데이트 할 수 있도록

var v = new View({ model: m }) 

그런 다음 뷰 컬렉션 모델의 이벤트에 바인딩합니다. 이보기는 백본의 컨트롤러 역할을하며 사용자 작업을 모델 또는 컬렉션으로 전달합니다.

$.getJSON('girls.json', function(data) { 
    $.each(data, function(key, val) { 
     list.push(new Girl(val)); 
    }); 

    var myGirls = new Girls(list); 
    var v  = new GirlsView({ collection: myGirls }); 
}); 

을 다음 GirlsView 컬렉션을 통해 회전 것이며, 각 모델에 대해 별도의 GirlView의를 만들 :

귀하의 초기화는 더 같이해야

var _this = this; 
this.collection.each(function(girl) { 
    var v = new GirlView({ model: girl }); 
    _this.$el.append(v.render().el); 
}); 

그런 다음, GirlView는 다음과 같이 렌더링 것 :

// This could go in initialize() if you're not certain that the 
// DOM will be ready when the view is created. 
template: _.template($('#girl_template').html()), 
render: function() { 
    this.$el.html(this.template(this.model.toJSON()); 
    return this; 
} 

결과적으로 각 모델 별보기에는 이벤트를 현지화하는 고유 한 el이 있습니다. 이는 또한 모든 것이 자체적으로 el에 잘 정리되어 있기 때문에 GirlView를 추가하거나 제거하는 것을 아주 쉽게 만듭니다.

+0

좋아, 내가 백본에서 모델보기의 개념을 얻은 것 같아. 나는 변화를 만들었지 만, 이제는 아무 것도 페이지에 나타나지 않는다. http://pastebin.com/96vhsDPu – nax

+0

@nax : 당신은'GirlsView '어디에서든지; 'this.collection.each' 루프는'initialize'보다는'render'에서 더 나을 것입니다 : http://jsfiddle.net/ambiguous/3fHkh/ –