4

ember.jsとcouchdbを使用してアプリケーションを実装しています。データベース アクセス レイヤーとして ember-resource を選択した理由は、ネストされた JSON ドキュメントを適切にサポートしているからです。

カウチデータベースはすべてのドキュメントでオプティミスティック ロックに属性 _rev を使用するため、データをカウチデータベースに保存した後、アプリケーションでこの属性を更新する必要があります。

これを実装する私の考えは、データベースに保存した直後にデータをリロードし、ドキュメントの残りの部分で新しい _rev を取得することです。

これが私のコードです:

// Since we use CouchDB, we have to make sure that we invalidate and re-fetch
// every document right after saving it. CouchDB uses an optimistic locking
// scheme based on the attribute "_rev" in the documents, so we reload it in
// order to have the correct _rev value.
didSave:     function() {
    this._super.apply(this, arguments);
    this.forceReload();
},

// reload resource after save is done, expire to make reload really do something
forceReload: function() {
    this.expire();  // Everything OK up to this location
    Ember.run.next(this, function() {
        this.fetch()  // Sub-Document is reset here, and *not* refetched!
            .fail(function(error) {
                App.displayError(error);
            })
            .done(function() {
                App.log("App.Resource.forceReload fetch done, got revision " + self.get('_rev'));
            });
    });
}

これはほとんどの場合に機能しますが、ネストされたモデルがある場合、フェッチが実行される直前にサブモデルが古いバージョンのデータに置き換えられます!

興味深いことに、フェッチ後、正しい (更新された) データがデータベースに保存され、間違った (古い) データがメモリ モデルに保存されますが、_rev 属性は (メイン オブジェクトのすべての属性と同様に) 正しいにもかかわらずです。

これが私のオブジェクト定義の一部です:

App.TaskDefinition = App.Resource.define({

url: App.dbPrefix + 'courseware',

schema: {
    id:          String,
    _rev:        String,
    type:        String,
    name:       String,
    comment:    String,
    task:        {
        type:   'App.Task',
        nested: true
    }
}
});

App.Task = App.Resource.define({

schema: {
    id: String,
    title:       String,
    description: String,

    startImmediate: Boolean,
    holdOnComment: Boolean,
    ..... // other attributes and sub-objects
}
});

問題が発生している可能性のあるアイデアはありますか?

ご提案ありがとうございます。

よろしく、 トーマス

4

1 に答える 1

5

保存するたびにデータをリロードせずに、データベースから新しいリビジョンを取得するためのはるかに優れたソリューションを見つけました。

が更新オプションでsave呼び出された場合、データベースからの応答がリソース オブジェクトにマージされます。ember-resource保存リクエストに対するcouchdbの答えは次のようなものです

{"ok":true,"id":"mydocument-123","rev":"10-5f3cb46df301143a966251148f88663d"}

したがって_rev、オブジェクトのプロパティをrevデータベースの値に設定するだけです。

すべての cupdb オブジェクトのスーパークラスとしてのアプリケーション固有のリソース クラスは次のとおりです。

App.Resource = Ember.Resource.extend({

    save: function(options) {
        options = options || {};
        options.update = true; // sets id and rev after saving in ember-resource; rev is copied to _rev in didSave callback!
        this.set('rev', undefined);
        return this._super(options);
    },

    // we get the new revision in the "rev" attribute of the response from the save-request.
    // since we set options.update to true, we get this value in the attribute "rev", which we simply copy to "_rev"
    didSave:     function() {
        this._super.apply(this, arguments);
        this.set('_rev', this.get('rev'));
    }

    .... // other properties and functions
});

リソースは次のように定義されます。

App.TaskExecution = App.Resource.define({

    ....

    schema: {

        id:   String,
        _rev: String,
        rev:  String,
        type: String,
        .....  // other attributes
    }

});

これまでのところかなりうまく機能します....

于 2012-06-19T21:13:51.727 に答える