5

私はbackbone.jsを使用して、バディリスト(別名Roster)を実装しています。名簿コレクションと個人の私のバックボーンビューはrosterEntry次のとおりです。

    Slx.Roster.Views.RosterEntry = Backbone.View.extend({
    tagName: "li",
    className : "rosterEntry clearfix",
    templateSelector: '#rosterEntryTemplate',

    initialize: function() {
        _.bindAll(this, 'render');
        this.model.bind('change', this.render);
        this.model.bind('remove', this.remove);
        this.template = _.template($("#rosterEntryTemplate").html());
    },

    remove: function () {
        debug.log("Called remove event on model");
        $(this.el).remove();
    },
    render: function() {
        var renderedContent = this.template(this.model.toJSON());
        this.id = this.model.Id;
        $(this.el).attr('id', "friendid-" + this.model.get("id")).html(renderedContent);
        return this;
    }
});

    Slx.Roster.Views.Roster = Backbone.View.extend({
        el: "div#roster-container",
        initialize: function () {
            _.bindAll(this, 'render', 'add', 'remove');
            this.template = _.template($("#rosterTemplate").html());
            this.collection.bind('reset', this.render);
            this.collection.bind('add', this.add);
            this.collection.bind('remove', this.remove);
        },
        add: function (rosterEntry) {
            var view = new Slx.Roster.Views.RosterEntry(
                {
                    model: rosterEntry
                });
            $(this.el).append(view.render().el);
        },
        remove: function (model) {  // if I ommit this then the whole collection is removed!!
            debug.log("called remomve on collection");
        },
        render: function () {
            var $rosterEntries, collection = this.collection;

            $(this.el).html(this.template({}));
            $rosterEntries = this.$('#friend-list');

            _.each(collection.models, function (model) {
                var rosterEntryView = new Slx.Roster.Views.RosterEntry({
                    model: model,
                    collection: collection
                });

                $(this.el).find("ul#friend-list").append(rosterEntryView.render().el);
            }, this);

            return this;
        }
    })

私は今のところFirebugコンソールを使用してテストしており、次を実行することで名簿に問題なくデータを入力できます。

collection = new Slx.Roster.Collection
view = new Slx.Roster.Views.Roster({collection:collection})
collection.fetch()

Firebugコンソールで以下を実行することにより、コレクションへの追加も正常に機能します。

collection.add(new Slx.Roster.Model({username:"mickeymouse"})

そして、新しいrosterEntryものが名簿に追加されます。

私の問題は、collection.remove(5)メモリ内のコレクションから削除されますが、DOMを更新するために何もしないことです。

不思議なことにremove()、名簿ビューから関数を省略すると、名簿のすべてのエントリが削除されます。コンソールログ以外に何も含まれていないこのメソッドを追加すると、名簿とRosterEntryビューの両方でremoveメソッドが呼び出されます。理由はわかりませんが、順序が狂っています。

["Called remove event on model"]
["called remomve on collection"]

RosterEntryモデルからremove関数を削除すると、次のエラーが発生します。

TypeError: this.$el is undefined
this.$el.remove();

私は何が間違っているのですか?コレクションから削除されたときにDOMから要素を削除するにはどうすればよいですか?

4

3 に答える 3

2

contextすべてのイベントのバインド定義に問題があると思います。

これを変更してみてください:

this.model.bind('remove', this.remove);

このため:

this.model.bind('remove', this.remove, this);

でこれを解決しようとしたことは知っていますがbindAll、リストされたメソッドへのすべての呼び出しを実際のオブジェクトのコンテキストでラップしていますが、他のオブジェクトで同じメソッドをbindAll呼び出している場合、これは何もできません:)。

更新しました

私はもっ​​と読んでいます..のように見えbindAll、コマンドの3番目のパラメータbindはまったく同じです。だから多分あなたはどちらか一方を使うことができます。

で機能していないのは、行に追加するのを忘れたためですコードを調べてください。そして、私の提案はそれを修正しました。なぜなら、私が言うように、両方のアプローチが同じことをするからです。bindAllmodel.remove_.bindAll(this, 'render')

render, remove, ...これが行っているのは、リストされたメソッドへの呼び出し( 1つの場合または他の場合)が実際のオブジェクトへの参照としてthis.remove解釈されることを保証することです。thisこれはばかげているように見えるかもしれませんが、JSthisでは非常に不安定です。

あなたがまだthis物事に混乱していても心配しないでください、私はそれを長い間扱ってきましたが、それでも完全に一致しているわけではありません。

たぶん、このようなエッセイは私たちを助けることができます。

于 2012-04-16T18:33:44.840 に答える
0

次のことを試しましたか?

this.listenTo(this.model, "remove", this.remove);

それは私にとってはうまくいくようで、私はそれが少し良く読める方法が好きです。

バックボーンドキュメントへのリンク

于 2013-04-26T19:32:31.433 に答える
-1

モデルとコレクションの両方で削除する必要があるため、両方のビューのremoveメソッドが呼び出されている可能性があります。

RosterEntryの場合:

 this.model.bind('remove', this.remove);

名簿で:

this.collection.bind('remove', this.remove);
于 2012-04-16T17:57:53.373 に答える