Extjs 在mvc中加载要形成的数据

Extjs 在mvc中加载要形成的数据,extjs,sencha-touch-2,Extjs,Sencha Touch 2,在我的应用程序中,我有一个列表和详细信息(表单)。我想在单击列表项时将数据加载到详细信息视图(将数据设置为表单的文本字段)。对于列表和详细信息,我从远程服务器获取数据。我在关注MVC 现在,当单击listItem时,我可以从服务器获取数据并将其保存到存储,还可以显示详细视图。但我无法将数据从存储绑定到表单中的文本字段 模型 Ext.define('App.model.Details', { extend: 'Ext.data.Model', config: { f

在我的应用程序中,我有一个列表和详细信息(表单)。我想在单击列表项时将数据加载到详细信息视图(将数据设置为表单的文本字段)。对于列表和详细信息,我从远程服务器获取数据。我在关注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.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");
    }
})

请帮助将数据绑定到详细信息视图。

所以我猜您的联系人存储是在其他地方定义的,但由于此存储正在工作,您没有将代码粘贴到此处

因此,请简要介绍一下模型,您应该始终在其中定义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属性,因此表单知道要绑定到字段的存储/模型的哪个值
联系人型号:

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'}
        ]
    }
});
详细型号:

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'}
        ]
    }
});
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'
            }
        ]
    }
});
详细视图:

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

});

我们可以在几件事上争论,但我试图直截了当地说,让它起作用。如果你有更多的问题,请问,但这个例子是为我工作。在我看来,您可能不需要第二个存储,因为联系人详细信息可以嵌套在联系人存储中,并且可以使用存储的hasMany属性

所以我猜您的联系人存储区是在其他地方定义的,但由于此存储区正常工作,您没有将代码粘贴到此处

因此,请简要介绍一下模型,您应该始终在其中定义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属性,因此表单知道要绑定到字段的存储/模型的哪个值
联系人型号:

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'}
        ]
    }
});
详细型号:

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'}
        ]
    }
});
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'
            }
        ]
    }
});
详细视图:

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

});
我们可以在几件事上争论,但我试图直截了当地说,让它起作用。如果你有更多的问题,请问,但这个例子是为我工作。在我看来,您可能不需要第二个存储,因为联系人详细信息可以嵌套在联系人存储中,并且可以使用存储的hasMany属性

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

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

当您有一个存储时,您必须获得一个要加载的模型的引用,使用say getAt()或find()方法来加载