2014-11-07 2 views
0
// build a collection of players with this team ID 
this.collection = new PlayersCollection(App.data.players.where({team_id: this.model.id})); 

이렇게하면 this.collection = App.data.players;은 새로운 컬렉션 인 컬렉션과 관련이 있습니다. 새 컬렉션을 어떻게들을 수 있습니까?백본에서 사용자 지정 컬렉션을 수신합니까?

marioette에서는 collectionViews, compositeViews 및 itemViews가 포함 된 팀 콜렉션에 플레이어 컬렉션을 전달합니다.

팀 collectionView> 팀의 CompositeView> 플레이어 itemView 팀의 CompositeView 내부

나는 특정 팀의 ID와 일치하는 새로운 PlayersCollection로 this.collection을 정의합니다. 이 렌더링은 완벽하지만 새 플레이어를 추가하면 페이지를 새로 고치지 않고도 다시 렌더링 할 수 있습니다.

addPlayer: function(e) { 
    e.preventDefault(); 

    var $newPlayer = this.$el.find('input.player_name'); 

    var Player = { 
     player_name : $newPlayer.val(), 
     team_id  : this.model.id 
    } 

    App.data.players.create(Player); 
    $newPlayer.val(''); 

}, 

다음은 대부분 코드입니다. 새 플레이어를 추가/생성하려고하고 listenTo으로보기를 업데이트하려고합니다. 그러나이 방법은 컬렉션을 정의하는 전통적인 방법이 아니므로 바인딩하는 방법을 찾아야합니다.

Teams.js :

var Marionette = require('backbone.marionette'), 
    playerView = require('./player'), 
    PlayersCollection = require('../../collections/players'); 

var teamView = Marionette.CompositeView.extend({ 
    events: { 
     'submit #AddPlayer': 'addPlayer' 
    }, 
    initialize: function() { 
     // anytime something within this specific team changes, render 
     this.listenTo(this.model, 'change', this.render); 

     // build a collection of players with this team ID 
     this.collection = new PlayersCollection(App.data.players.where({team_id: this.model.id})); 

    }, 
    addPlayer: function(e) { 
     e.preventDefault(); 

     var $newPlayer = this.$el.find('input.player_name'); 

     var Player = { 
      player_name : $newPlayer.val(), 
      team_id  : this.model.id 
     } 

     App.data.players.create(Player); 
     $newPlayer.val(''); 

    }, 
    itemView: playerView, 
    appendHtml: function(collectionView, itemView){ 
     collectionView.$('.the-players').append(itemView.el); 
    } 
}); 

module.exports = CollectionView = Marionette.CollectionView.extend({ 
    initialize: function() { 
     this.listenTo(this.collection, 'change', this.render); 
    }, 
    itemView: teamView 
}); 

Players.js :

var Marionette = require('backbone.marionette'); 

module.exports = playerView = Marionette.ItemView.extend({ 
    className: 'players-wrap row', 
    template: require('../../../templates/teams/player.hbs'), 
    events: { 
     'mouseenter .player-image': 'playerOn', 
     'mouseleave .player-image': 'playerOff', 
     'click .player-image': 'playerClicked', 
     'keydown': 'on_keypress', 
     'click .one-point': 'onePoint', 
     'click .two-point': 'twoPoint', 
     'click .three-point': 'threePoint' 
    }, 
    initialize:function() { 
     _.bindAll(this, 'on_keypress'); 
     $(document).bind('keydown', this.on_keypress); 
     this.listenTo(this.model, 'change', this.render); 
     this.$el.attr('data-player', this.model.get('player_name').replace(/\s+/g,"_").toLowerCase()); 
     window.play = this.model; 
    }, 
    playerOn:function(e) { 
     this.$el.addClass('hover'); 
     this.findPlayer(this.model.get('player_name'), 'add');  
    }, 
    playerOff:function() { 
     this.$el.removeClass('hover'); 
     this.findPlayer(this.model.get('player_name'), 'remove'); 
    }, 
    playerClicked:function() { 
     this.$el.toggleClass('hover-clicked'); 
     this.findPlayer(this.model.get('player_name'), 'toggle'); 
    }, 
    findPlayer:function(name, action) { 
     var player = $('.data-wrap .player-data[data-player='+ name.replace(/\s+/g,"_").toLowerCase() +']'); 
     if(action === 'toggle') { player.toggleClass('show-confirmed-clicked') } 
     if(action === 'add') { player.addClass('show-player-data') } 
     if(action === 'remove') { player.removeClass('show-player-data') } 
    }, 
    onePoint:function(e) { 
     var addStat = parseInt(this.model.get('points')) + 1;   
     this.model.set('points', addStat); 
     this.model.save(); 
    }, 
    twoPoint:function(e) { 
     var addStat = parseInt(this.model.get('points')) + 2;   
     this.model.set('points', addStat); 
     this.model.save(); 
    }, 
    threePoint:function(e) { 
     var addStat = parseInt(this.model.get('points')) + 3;   
     this.model.set('points', addStat); 
     this.model.save(); 
    }, 
    on_keypress:function(e) { 
     this.keyStat(e, 49, 'points', 1); // 1 point 
     this.keyStat(e, 50, 'points', 2); // 2 points 
     this.keyStat(e, 51, 'points', 3); // 3 points 
     this.keyStat(e, 82, 'rebounds', 1); // R rebounds 
     this.keyStat(e, 83, 'steals', 1); // S steals 
    }, 
    keyStat:function(e, keyVal, stat, number) { 
     if(e.keyCode == keyVal && !e.ctrlKey) { 
      if(this.$el.hasClass('hover')) { 
       var addStat = parseInt(this.model.get(stat)) + number;   
       this.model.set(stat, addStat); 
       this.model.save(); 
      } 
     } 
    }, 
    templateHelpers:function(){ 
     return { 
      name_format: this.model.get('player_name').replace(/\s+/g, '_').toLowerCase() 
     } 
    } 
}); 

답변

1

난 당신이의 CompositeView의 컬렉션에 새 모델을 추가하는 장소를 찾을 수 없습니다? CompositeView 컬렉션이 아닌 App.data.players.create(Player); 만 찾았습니다. App.data.players 당신이 그것 때문에 당신은 서버에 지속 create를 사용하는 원격 서버와 동기화 유지해야하는 또 다른 Backbone.Collection 인 경우

, 다음과 같이 addPlayer을 변경

addPlayer: function(e) { 
    e.preventDefault(); 

    var $newPlayer = this.$('input.player_name'); 

    var Player = { 
     player_name : $newPlayer.val(), 
     team_id  : this.model.id 
    } 

    var newPlayer = App.data.players.create(Player); 
    this.collection.add(newPlayer); 
    $newPlayer.val(''); 

}, 

CompositeView은 컬렉션의 "add"이벤트를 포착하고 새로운 itemView를 추가합니다. 도와 주시면 알려주세요.

그냥 참고

:는 코드의 리뷰를 검토 한 나는 Teams.js에서 appendHtml이 렌더링 성능이 향상됩니다 .the-players의 값 itemViewContainer 속성을 제거 할 수 있다는 것을 발견했다.

+0

안녕하세요, 도움을 주셔서 감사합니다. –

+0

그래, 그것은 중첩 된 컬렉션이었고, 그 다음에는 플레이어를 팀 오브젝트 밖으로 가져 와서 플레이어 컬렉션을 글로벌하게 만들었습니다. 그 이유는 그것이 글로벌이기 때문에 발사되지 않을 가능성이 높습니다. 내가보기에 그것을 전달해야합니다. 당신 말이 맞아요, 제가 어떻게 합성보기로 그 일을 할 수 있는지 알아야합니다. –

+0

좋아, 더 읽기가 좋아 보인다. 내가 그것을 시도하자. –

관련 문제