2016-04-30 9 views
0

タイトルはすべてそれを示しています。子レコードが追加されたときにsession.getSaveBatch()が未定義になっている理由 - Ext 5.1.1

私は2つの関連モデルUser & Roleを持っています。それから私は、ユーザーのグリッドと彼の役割など、ユーザーのデータを編集するためのフォームを持っている

Ext.define('App.model.security.User', { 
    extend: 'App.model.Base', 

    entityName: 'User', 

    fields: [ 
     { name: 'id' }, 
     { name: 'email'}, 
     { name: 'name'}, 
     { name: 'enabled', type: 'bool'} 
    ], 

    manyToMany: 'Role' 
}); 

ユーザーとして定義された役割を持っています。

私がユーザーからロールを追加または削除しようとすると、後でsession.getSaveBatch()への呼び出しが未定義を返し、サーバーに変更を送信するためのバッチを開始できません。

どうすればこの問題を解決できますか?

答えて

0

これは興味深いことですが、私はこの簡単な問題を解決してExtについて多くのことを学びました。

私が見つけた解決策は、BatchVisitorクラスをオーバーライドして、SessionクラスのprivateメソッドvisitDataから生成されたイベントonCleanRecordのイベントハンドラを使用することです。

各レコードについて、マトリックスの左側のエンティティを探し、変更があれば、BatchVisitorオリジナルクラスで定義されているonDirtyRecordのハンドラを呼び出します。

コード:それは私のニーズのために非常によく動作し

Ext.define('Ext.overrides.data.session.BatchVisitor', { 
    override: 'Ext.data.session.BatchVisitor', 

    onCleanRecord: function (record) { 
     var matrices = record.session.matrices 
      bucket = null, 
      ops = [], 
      recordId = record.id, 
      className = record.$className; 

     // Before anything I check that the record does not exists in the bucket 
     // If it exists then any change on matrices will be considered (so leave) 
     try { 
      bucket = this.map[record.$className]; 
      ops.concat(bucket.create || [], bucket.destroy || [], bucket.update || []); 

      var found = ops.findIndex(function (element, index, array) { 
       if (element.id === recordId) { 
        return true; 
       } 
      }); 

      if (found != -1) { 
       return; 
      } 

     } 
     catch (e) { 
      // Do nothing 
     } 

     // Now I look for changes on matrices 
     for (name in matrices) { 
      matrix = matrices[name].left; 

      if (className === matrix.role.cls.$className) { 
       slices = matrix.slices; 

       for (id in slices) { 
        slice = slices[id]; 
        members = slice.members; 

        for (id2 in members) { 
         id1 = members[id2][0]; // This is left side id, right side is index 1 
         state = members[id2][2]; 

         if (id1 !== recordId) { // Not left side => leave 
          break; 
         } 

         if (state) { // Association changed 
          this.onDirtyRecord(record); 
          // Same case as above now it exists in the bucket (so leave) 
          return; 
         } 
        } 
       } 
      } 
     } 
    } 
}); 

、おそらくそれは文句を言わない他の人のために最善の解決策になるが、とにかく出発点となることができます。

最後に、まだ明確でない場合は、メソッドgetSaveBatchにリレーションシップの変更を検出する機能があります。

0

よく読んだ後、私は、Extが少なくとも5.1.1では2つのモデル間の変更された関係を保存しないことを発見しました。 私は左のモデルにデフォルトの値falseを指定して(デフォルトではisDirtyという名前の)名前付きフィールドを配置し、セッションに強制的にgetSaveBatchを使ってサーバーに更新を送信するように設定することでこれを回避しなければなりませんでした。

後で、自動的に関連付けを保存できるBatchVisitorクラスまたはカスタムBatchVisitorクラスにオーバーライドを書き込むコードを掘り下げます。

これは、2つのモデル間の関連付けだけを保存し、関連するエンティティの1つを変更する場合に、関連付けが保存バッチで送信されることに注意してください。

関連する問題