2

最終的にこの属性をパーマリンクとして使用できるように、新しいモデルが作成されたときに特定の属性がコレクション全体で一意であることを確認したいと思います。

リスト コレクションとリスト モデルがあります。(コーヒースクリプト)

class App.Models.List extends Backbone.Model
  defaults:
    name: "My New List"

class App.Collections.ListSet extends Backbone.Model
  model: App.Models.List

新しいモデルが ListSet に追加されたときに、その名前のモデルが既に存在する場合は、name 属性の末尾に自動インクリメント番号を追加したいと考えています。たとえばMy New List 1、モデルがMy New List.

邪魔になってエラーを表示したくはありませんが、問題を自動的に修正するだけです。インクリメント整数の追加の背後にあるロジックには満足していますが、コードをどこに配置して変更を加えるかについて指示が必要です。

4

2 に答える 2

1

これはあなたのために働くかもしれません:

App.Models.List = Backbone.Model.extend({
    initialize: function(attrs) {
        this.set(attrs);
        this.set({originalName: attrs.name});

        var count = yourCollection.reduce(function(count,model){
            return count + (model.get('originalName') === this.get('originalName') ? 1 : 0);
        },0,this);

        if(count > 0) {
            this.set({name: this.get('name') + ' ' + count});
        }
    }
});

ここにデモがあります: jsFiddle DEMO

これがすべきことは、モデルを初期化するたびに、コレクションをスキャンして、他のモデルに同じ があるかどうかを確認することですoriginalName。その場合は、結果を name 属性に追加します。

===更新===

コレクションからモデルを分離するために、モデルがコレクションに追加されたときに変更を行う方がおそらく良いことに気づきました。更新されたコード スニペットは次のとおりです。

App.Models.List = Backbone.Model.extend({
    initialize: function(attrs) {
        this.set({originalName: attrs.name});
    }
});

App.Collections.Lists = Backbone.Collection.extend({
    model: App.Models.List,
    initialize: function() {
        this.on('add',this.resolveNameConflict,this);
    },
    resolveNameConflict: function(model){
        var count = this.reduce(function(c,m){
            return c + (m.get('originalName') === model.get('originalName') ? 1 : 0);
        },0);
        if(count > 1) {
            model.set({name: model.get('originalName') + ' ' + (count-1)});
        }
    }
});

およびデモ: jsFiddle DEMO

于 2012-07-16T18:51:47.547 に答える
0

更新:ジャックワンダーの答えはより良い解決策です... 私の素朴な解決策と彼の単純な解決策を比較して対比するのは興味深いので、ここにとどめておきます。初心者のプログラマーは、この 2 つを評価することで何かを学ぶことができます。:-)


刺してみます。あなたはこのようなことをするかもしれません。基本的に、モデルをコレクションに追加するたびに名前チェックを行う eventListener を追加します。nameTracking配列は、一意の名前フラグメントと、名前ルートの最後のカウントを追跡するカウンターを持つ名前オブジェクトの一種のカタログです。増分アプリケーションに役立ちます。

ListSet = Backbone.Collection.extend({

    initialize: function() {
        this.nameTracking = [];
        this.on('add', this.pushModelName, this);
    },

    pushModelName: function(model, collection) {

        // First, look through current collection for a model with same name
        var duplicate = this.find(function(listModel) {
            return model.get('name') === listModel.get('name');
        });

        // If duplicate exists, we lookup the name and counter in the nameTracking array.
        if (duplicate) {

            var nameObj = _.find(this.nameTracking, function(nameObj) {
                return nameObj.name === model.get('name');
            });

            // We increment the counter so that our added model is appended with the
            // correct, "latest" increment/indicator
            nameObj.count = nameObj.count++;
            model.set('name', model.get('name') + '_' + nameObj.count);

        // Otherwise it doesn't exist so we push the name into our nameTracking array
        } else {    // Not a duplicate, new name

            var modelName = model.get('name');

            this.nameTracking.push({
                'name': modelName,
                'count': 0
            });

        }
    }
});

nameTracking[]注意すべきことは、これは、追加するモデルが新しいモデルであり、コレクションに既に存在するモデルの id を既に持っているモデルではないことを前提としていることです (クローンではありません)。コレクションの初期化、またはfetch()これはゼロから始めていることを前提としているためです。モデルの削除や名前カウンターの更新については扱いませんが、このスケッチに基づいて、そのような性質のものが必要な場合は実装するのは難しくありません。

于 2012-07-16T18:18:19.173 に答える