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

所以我猜你的联系人商店是在其他地方定义的,但是由于这个正在工作,你没有在这里粘贴代码。

所以关于模型的一个快速说明,您应该始终定义一个 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 非常有用的原因)
  • 设置字段集而不是面板的记录

我还没有机会尝试,但我会在今晚晚些时候尝试。不过还是试试吧。

- 编辑 -

好的,我终于可以为您编写代码了。

您的代码中有一些问题。我真的不知道你为什么需要两家商店,但假设你需要。我将提供我使用的所有文件(两个商店、两个模型、三个视图和控制器)。您的代码中有三个主要错误:

  • 您不应该加载第二个商店并尝试在之后立即获取记录。为此使用和“加载”或“刷新”事件
  • 表单的 SetValues 是正确使用的函数
  • 您在表单中缺少 name 属性,以便表单知道要绑定到该字段的 store/model 的哪个值。

联系型号:

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

联系商店:

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'}
        ]
    }
});

详细型号:

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'}
        ]
    }
});

详情商店:

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'}
        ]
    }
});

联系方式:

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'
            }
        ]
    }
});

详细视图:

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 属性。

于 2013-03-26T16:13:34.437 回答
1

使用 form.setRecord() 将记录加载到表单中

确保您的表单元素具有与模型名称属性匹配的名称属性值

由于您有商店,因此您必须获取一个要加载的模型的引用,使用 getAt() 或 find() 方法在您的商店中获取或查找模型

于 2013-03-26T17:03:17.170 回答