开发者

Backbone.js: Existing View events continue to fire

开发者 https://www.devze.com 2023-03-22 19:18 出处:网络
In my View, I have events that fire onclick of an A element. Unfortunately, when I create a new View from a Model, the existing events of first Model/View pair continue to fire. What ends up happening

In my View, I have events that fire onclick of an A element. Unfortunately, when I create a new View from a Model, the existing events of first Model/View pair continue to fire. What ends up happening is the save() continues to use the existing Model instead of the new one and I can never create a new Model and use that Model without refreshing the page. I'm very new to backbone.js, but is there a way to save() that existing Model but remove its View? If I'm not making sense, please let me know.

Any help would be greatly appreciated! Thanks so much.

$(function() {

var Game = Backbone.Model.extend({

    defaults: {
        begun: false,
        currentPlayer: 1
    },

    play: function() {
        console.log(this.id);
        var player = (this.get('currentPlayer') == 1) ? 2 : 1;
        this.save({ 'currentPlayer': player, 'begun': true });
    }

});

var GameList = Backbone.Collection.extend({

    model: Game,

    localStorage: new Store('game'),

    existing: function() {
        return this.filter(function(game){ return game.get('begun'); });
    },

    unused: function() {
        return this.filter(function(game){ return !game.get('begun'); });
    }

});

var Games = new GameList;

var GameView = Backbone.View.extend({

    el: $('#board'),

    events: {
        'click li a': 'play'
    },

    initialize: function() {
        _.bindAll(this, 'clear');
        this.model.bind('destroy', this.clear);
    },

    render: function() {
        console.log(this.model.id);
        this.clear();
    },

    clear: function() {
        this.el.find('li a span').html('');
    },

    play: function(event) {
        $(event.currentTarget).find('span').html(this.model.get('currentPlayer'));
        this.model.play();
        return false;
    }

});

var AppView = Backbone.View.extend({

    el: $('#info'),

    events: {
        'click #new-game': 'newGame'
    },

    initialize: function() {
        _.bindAll(this, 'startGame', 'getGame');
        Games.bind('add', this.startGame);
        Games.bind('reset', this.getGame);

        Games.fetch();
    },

    newGame: function(event) {
        Games.create();
        return false;
    },

    getGame: function() {
        var existing = Games.existing();
        var unused = Games.unused();
        if(existing.length) this.startGame(existing[0]);
        else if(unused.length) this.startGame(unused[0]);
        else Games.create();
    },

    startGame: function(game) {
        var view = new GameView({ model: game });开发者_Go百科
        view.render();
    }

});

var App = new AppView;

});


There is only ever one instance of a model. You can have many views of the same model. When one view expires, just remove it from the DOM.

$(this.el).remove();


Events in Backbone view are delegated. In your case this means that click on every element that matches '#board li a' selector will fire the 'play' method. Since you are using the same element for every game view ('#board'), every click on 'li a' inside it will trigger all 'play' methods of all game views, thus saving all the models.

So, if you can have multiple game views on your page, use separate element for each of them (just remove el: $('#board') from your view declaration and append created view manually to '#board'.

Or, if you can have only one game view, override a remove method of your view to undelegate all events from '#board' and call remove() every time before creating a new game view:

remove: function() {
    this.$el.off().remove()
}
0

精彩评论

暂无评论...
验证码 换一张
取 消