1

私のアプリケーションでは、リストと詳細(フォーム)があります。リスト項目がクリックされたときにデータを詳細ビュー(フォームのテキストフィールドにデータを設定)にロードしたいと思います。リストと詳細の両方について、リモートサーバーからデータを取得しています。私はMVCをフォローしています。

これで、listItemをクリックすると、サーバーからデータを取得して保存し、詳細ビューを表示することができます。しかし、ストアからフォームのテキストフィールドにデータをバインドすることはできません。

モデル

Ext.define('App.model.Details', {
    extend: 'Ext.data.Model',
    config: {
        fields: [
            {name: 'Name',  type: 'string'},
            {name: 'BillingStreet',  type: 'string'},
            {name: 'BillingCity',  type: 'string'}

        ]
    }
});

Ext.define('App.store.Details', {
    extend: 'Ext.data.Store',
    config: {
        model: 'App.model.Details',
        autoLoad :true,

        grouper : function(record) {
            return record.get('Name')[0];
        },
    }
});

リストビュー

Ext.define('App.view.View', {
    extend: 'Ext.List',
    alias:'widget.contactlist',
    fullscreen: true,
    id: 'contactlist',
    config:{
        disableSelection:true,
        store:'Contacts',
        itemTpl:'{Name}',
        items:[
        {
            xtype:'toolbar',
            docked:'top',
            title:'Leeds List'
        }

        ]
    }
});

詳細ビュー

Ext.define("App.view.ListDetail", {
    extend: "Ext.form.Panel",
    requires: "Ext.form.FieldSet",
    alias: "widget.listDetail",
    config:{
        scrollable:'vertical'
    },
    initialize: function () {

        this.callParent(arguments);



        var topToolbar = {
            xtype: "toolbar",
            docked: "top",
            title: "Details"

        };


        this.add([
                  topToolbar,
                  { xtype: "fieldset",
                      items: [{
                          xtype: 'textfield',
                          store: 'Details',
                          value : 'Name',
                          label: 'Name'
                      },
                      {
                          xtype: 'emailfield',
                          store: 'Details',
                          value : 'BillingStreet',
                          label: 'Email'
                      },
                      {
                          xtype: 'passwordfield',
                          store: 'Details',
                          value : 'BillingCity',
                          label: 'Password'
                      }

                      ]
                  }
              ]);


    }

});

コントローラ

Ext.define('App.controller.Main', {

    extend: 'Ext.app.Controller',

       config: {
        refs: {
            // We're going to lookup our views by xtype.
            contactlist: "contactlist",
            contactdetail: "listDetail",
            //f_name:"#f_name"


        },
        control: {
            contactlist: {
                // The commands fired by the notes list container.
                itemtap: "oneditLeadCommand"

            }

        },

        routes: {
            'contactlist': 'activateList'
        }
    },

    activateList: function ()
    {
        Ext.Viewport.animateActiveItem(this.getContactlist(), this.slideRightTransition);
    },

    slideLeftTransition: { type: 'slide', direction: 'left' },
    slideRightTransition: { type: 'slide', direction: 'right' },

    oneditLeadCommand: function (list, index, target, record, e, eOpts)
    {

        console.log("onEditLead"+record.data.Id);
        this.activateLeadDetail(record);


    },

    activateLeadDetail: function (record)
    {

      var contactDetail = this.getContactdetail();
      //console.log("activateLeadDetail"+contactDetail.textfield);
      //contactDetail.setRecord(record); // load() is deprecated.
      //this.getF_name().setDisplayField("");


      store = Ext.StoreMgr.get('Details');
      //console.log("activateLeadDetail"+store);
      store.setProxy({
        type: 'ajax',
        url : 'http://10.0.2.2:8080/SalesForce/leads/get-lead-details/00D90000000jvoU!AR4AQB6Xcjz4UNBKf12WOcYHWc31QxK2.fXTcbCvOq.oBosCrjBezhqm8Nqc1hrf8MKK5LjLAu8ZC5IqB1kdpWvJGLdWd5pJ/'+record.data.Id,  //  the json file that holds all our contact info.
        reader: {
            type: 'json'
           }
       });
      store.load();
      var record1 = Ext.StoreMgr.get('Details').getAt(0);
      console.log("activateLeadDetail"+record1);

      Ext.StoreMgr.get('Details').each(function(test){
            console.log("for loop"+test.data);
        });
      contactDetail.setRecord(record1);
      Ext.Viewport.animateActiveItem(contactDetail, this.slideLeftTransition);
   },
    // Base Class functions.
    launch: function () {
        this.callParent(arguments);

        console.log("launch");
    },
    init: function () {
        this.callParent(arguments);
        console.log("init");
    }
})

データを詳細ビューにバインドするのを手伝ってください。

4

2 に答える 2

4

したがって、Contacts Storeは別の場所で定義されていると思いますが、これは機能しているため、ここにコードを貼り付けませんでした。

したがって、モデルに関する簡単なメモです。ここでは、常にidPropertyを定義する必要があります。これは、Senchaがストアの「主キー」を定義するために内部的に使用するものであるため、ストアをリロード/更新するときに正しく機能します。

Ext.define('App.model.Details', {
    extend: 'Ext.data.Model',
    config: {
        idProperty: 'Name', // Or something from your server maybe?
        fields: [
            {name: 'Name',  type: 'string'},
            {name: 'BillingStreet',  type: 'string'},
            {name: 'BillingCity',  type: 'string'}

        ]
    }
});

次に、listViewでconfigメソッドを使用したときに、ListDetailビューでinitializeメソッドを使用したのはなぜですか。代わりに構成を指定すると、次のような操作を行うことで、このコンポーネントの一部を別の場所でより簡単に再利用できるようになります。

items: [
    {
        xtype: 'ListDetail',
        anyOtherAttribute: value
    }
]

しかし、それはここではちょっと範囲外です。とにかく。ここで間違っているのは、パネルの各フィールドにストアを定義していることだと思います。申し訳ありませんが、仮説を検証できませんが、次のようにします。

Ext.define("App.view.ListDetail", {
    extend: "Ext.form.Panel",
    requires: "Ext.form.FieldSet",
    alias: "widget.listDetail",
    config:{
        scrollable:'vertical'
        items:[
           {
               xtype: "toolbar",
               docked: "top",
               title: "Details"
           },
           { 
                xtype: "fieldset",
                itemId: 'detailedListFiledset', //Overall, prefer itemId
                items: [
                    {
                         xtype: 'textfield',
                         value : 'Name',
                         label: 'Name' // may be you want placeholders here?
                    },
                    {
                         xtype: 'emailfield',
                         value : 'BillingStreet',
                         label: 'Email' // and here..
                    },
                    {
                         xtype: 'passwordfield',
                         value : 'BillingCity',
                         label: 'Password' // and here..
                     }

                  ]
             }
        ]
    }
});

了解しました。問題はコントローラーにあるようです。

  • フィールドセットに参照を追加します
  • ストアへの参照を追加します
  • ストアがロードされたときにアフターロードコールバックを作成する(詳細)
  • 毎回ストアをクリアするか、データを追加してフィルターに適用し、正しいレコードを取得します(これが、idPropertyが非常に役立つ理由です)
  • パネルではなく、フィールドセットのレコードを設定します

私はそれを試す機会がありませんでしたが、今夜遅くにそれをします。しかし、それを試してみてください。

- 編集 -

さて、私はついにあなたのために何かをコーディングするために阿部になりました。

コードにいくつかの問題がありました。なぜ2つの店舗が必要なのかはよくわかりませんが、必要だとしましょう。使用したすべてのファイル(2つのストア、2つのモデル、3つのビュー、およびコントローラー)を提供します。あなたのコードでは3つの主なことが間違っていました:

  • 2番目のストアをロードして、すぐにレコードを取得しようとしないでください。そのために'load'または'refresh'イベントを使用します
  • フォームのSetValuesは、使用する正しい関数です
  • フォームにnameプロパティがないため、フォームはストア/モデルのどの値にバインドするかを認識しています。

ContactModel:

Ext.define('App.model.Contact', {
    extend: 'Ext.data.Model',
    config: {
        idProperty: 'id',
        fields: [
            {name: 'id', type: 'int'},
            {name: 'name',  type: 'string'}
        ]
    }
});

ContactStore:

Ext.define('App.store.ContactStore', {
    extend: 'Ext.data.Store',
    requires:['App.model.Contact'],
    config: {
        storeId: 'ContactStore',
        model: 'App.model.Contact',
        autoLoad :true,
        data: [
            {id: 0, name: 'Foo'},
            {id: 1, name: 'Bar'}
        ]
    }
});

DetailModel:

Ext.define('App.model.Detail', {
    extend: 'Ext.data.Model',
    config: {
        idProperty: 'id',
        fields: [
            {name: 'id', type: 'int'},
            {name: 'name',  type: 'string'},
            {name: 'billingStreet',  type: 'string'},
            {name: 'billingCity',  type: 'string'}
        ]
    }
});

DetailStore:

Ext.define('App.store.DetailStore', {
    extend: 'Ext.data.Store',
    config: {
        model: 'App.model.Detail',
        autoLoad :true,
        data: [
            {id: 0, name: 'Foo', billingStreet:'here', billingCity: 'Somewhere'},
            {id: 1, name: 'Bar', billingStreet:'there', billingCity: 'Somewhere else'}
        ]
    }
});

ContactView:

Ext.define('App.view.ContactList', {
    extend: 'Ext.List',
    xtype: 'contactList',
    fullscreen: true,

    config: {
        itemId: 'contactList',
        store:'ContactStore',
        emptyText: 'test',
        itemTpl: new Ext.XTemplate(
            '{name}'
        ),
        items:[
            {
                xtype:'toolbar',
                docked:'top',
                title:'Leeds List'
            }
        ]
    }
});

DetailView:

Ext.define('App.view.Detail', {
    extend: 'Ext.form.Panel',
    requires: ['Ext.form.FieldSet'],
    xtype: "detail",
    config:{
        scrollable:'vertical',
        items: [
          {
            xtype: 'toolbar',
            docked: 'top',
            title: 'Details'
          },
          { 
            xtype: 'fieldset',
            itemId: 'detailForm',
            items: [{
                xtype: 'textfield',
                store: 'Details',
                name: 'name',
                placeHolder : 'Name',
                label: 'Name'
              },
              {
                xtype: 'textfield',
                store: 'Details',
                placeHolder : 'BillingStreet',
                name: 'billingStreet',
                label: 'BillingStreet'
              },
              {
                xtype: 'textfield',
                store: 'Details',
                placeHolder : 'BillingCity',
                name: 'billingCity',
                label: 'BillingCity'
              }
            ]
          }
        ]
    }
});

メインビュー:

Ext.define('App.view.Main', {
    extend: 'Ext.Container',
    xtype: 'main',
    config: {
        layout: 'hbox',
        items: [
            {
                xtype: 'contactList',
                flex:1
            },
            {
                xtype: 'detail',
                flex:2.5
            }
        ]
    }
});

メインコントローラー:

Ext.define('App.controller.Main', {
    extend : 'Ext.app.Controller',
    requires: [
        'Ext.Toolbar',
        'Ext.List',
        'App.store.ContactStore',
        'App.store.DetailStore',
        'App.view.Detail',
        'App.view.ContactList'
    ],
    config: {
        //@private
        detailStore: null,
        currentListIndex: -1,
        views : [
            'App.view.ContactList',
            'App.view.Detail'
        ],
        refs: {
            list: 'contactList',
            detail: 'detail',
            detailForm: 'detail #detailForm'
        },
        control: {
            list: {
                itemtap: 'handleItemTapList'
            }
        }
    },
    launch: function() {
        var store = Ext.getStore('DetailStore');
        store.on('refresh', 'handleDetailStoreLoad', this);
        this.setDetailStore(store);
    },
    handleItemTapList: function(list, index, target, record) {
        this.setCurrentListIndex(index);
        this.getDetailStore().load();
    },
    handleDetailStoreLoad: function (store) {
        debugger;
        var record = store.getAt(this.getCurrentListIndex());
        this.getDetail().setValues(record.data);
    }

});

私たちはいくつかのことについて議論することができましたが、私は要点にまっすぐに行き、それを機能させることを試みました。さらに質問がある場合は質問してくださいが、この例は私のために働いています。私の意見では、連絡先の詳細はCOntactストアにネストでき、ストアのhasManyプロパティを使用できるため、2番目のストアは必要ないかもしれません。

于 2013-03-26T16:13:34.437 に答える
1

form.setRecord()を使用して、レコードをフォームにロードします

フォーム要素の名前プロパティ値がモデル名のプロパティと一致していることを確認してください

ストアがあるので、ロードする1つのモデルへの参照を取得する必要があります。たとえば、getAt()またはfind()メソッドを使用して、ストア内のモデルを取得または検索します。

于 2013-03-26T17:03:17.170 に答える