Model view controller Ext.js 4窗口,表单为cals servlet,返回JSON,但无法填充gridpanel
我正在使用Ext.js4和MVC。我有一个弹出窗口,向用户询问一些标准。该窗口调用servlet,servlet以JSON的形式返回数据,然后填充网格。我可以通过Firefly看到JSON对象被返回。但是,未填充网格。原因是对servlet进行了后续调用。这是因为我在两个地方指定了URL。我知道这是错误的,但如果忽略其中一个,我会收到错误消息 这是app/controller/PSLocators.jsModel view controller Ext.js 4窗口,表单为cals servlet,返回JSON,但无法填充gridpanel,model-view-controller,extjs,datastore,gridpanel,formpanel,Model View Controller,Extjs,Datastore,Gridpanel,Formpanel,我正在使用Ext.js4和MVC。我有一个弹出窗口,向用户询问一些标准。该窗口调用servlet,servlet以JSON的形式返回数据,然后填充网格。我可以通过Firefly看到JSON对象被返回。但是,未填充网格。原因是对servlet进行了后续调用。这是因为我在两个地方指定了URL。我知道这是错误的,但如果忽略其中一个,我会收到错误消息 这是app/controller/PSLocators.js Ext.define('MyApp.controller.PSLocators', {
Ext.define('MyApp.controller.PSLocators', {
extend: 'Ext.app.Controller',
stores: [ 'PSLocators' ],
models: [ 'PSLocator' ],
views : [ 'pslocator.List' ]
});
这是app/model/PSLocator.js
Ext.define('MyApp.model.PSLocator',
{
extend: 'Ext.data.Model',
fields:
[
'id',
'name',
'address',
'city',
'state',
'zip',
]
});
这是app/store/PSLocators.js。这是第一个URL。这是一个不返回任何数据的。我不认为我应该在这里有代理{},但是如果我删除代理{},我会得到错误消息
uncaught exception: [Exception... "'You are using a ServerProxy but have not supplied it with a url.' when calling method: [nsIDOMEventListener::handleEvent]"
nsresult: "0x8057001c (NS_ERROR_XPC_JS_THREW_JS_OBJECT)"
location: "JS frame :: chrome://firebug/content/net/spy.js :: callPageHandler :: line 812" data: no]"
Ext.define('MyApp.store.PSLocators', {
extend: 'Ext.data.Store',
model: 'MyApp.model.PSLocator',
autoLoad: false, // see also activate() in grid panel
sortOnLoad: false, // sorted by SAS
proxy:
{
type: 'ajax',
url: MyGlobalData.contextPath + '/PSLocator',
reader:
{
type: 'json',
root: 'data', // the name of the array within the JSON dataset
totalProperty: 'results',
successProperty: 'success'
}
}
});
这是app/view/pslocator/List.js
。这是第二个URL。此url以JSON格式正确返回数据。如果删除url,则会收到错误消息“未捕获异常:未指定url”
是否有人可以帮助我,或者给我指出一个工作示例(提醒:我正在尝试使用MVC架构)。您应该将代理配置存储在模型中,而不是存储在ExtJS4中。另外,看起来您只是想将对门店的搜索限制在特定的门店编号。您不需要通过表单提交POST请求即可完成此操作。您应该向存储添加筛选器,以便服务器可以返回正确的数据 免责声明:我还没有测试过这段代码,但它应该足以让您继续 app/model/PSLocator.js
Ext.define('MyApp.model.PSLocator',
{
extend: 'Ext.data.Model',
fields:
[
'id',
'name',
'address',
'city',
'state',
'zip',
],
proxy:
{
type: 'ajax',
url: MyGlobalData.contextPath + '/PSLocator',
reader:
{
type: 'json',
root: 'data', // the name of the array within the JSON dataset
totalProperty: 'results',
successProperty: 'success'
}
}
});
Ext.define('MyApp.store.PSLocators', {
extend: 'Ext.data.Store',
model: 'MyApp.model.PSLocator',
autoLoad: false, // see also activate() in grid panel
sortOnLoad: false, // sorted by SAS,
remoteFilter: true // Needed so filter changes will go to the server
});
Ext.define('MyApp.view.pslocator.List' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.pslocatorlist',
store : 'PSLocators',
title : 'Store Locator',
id : 'pslocator.List',
autoScroll: true,
height: 400,
columnLines: true,
initComponent: function()
{
this.columns = [
{header: 'ID' , dataIndex: 'id' , flex: .05 , align: 'center' },
{header: 'Name' , dataIndex: 'name' , flex: .20 , align: 'left' },
{header: 'Address' , dataIndex: 'address' , flex: .20 , align: 'left' },
{header: 'City' , dataIndex: 'city' , flex: .10 , align: 'left' },
{header: 'State' , dataIndex: 'state' , flex: .05 , align: 'center' },
{header: 'Zip' , dataIndex: 'zip' , flex: .05 , align: 'center' }
];
this.callParent(arguments);
}
}); // Ext.define
Ext.define('MyApp.view.pslocator.Window', {
extend: 'Ext.Window',
alias: 'widget.storeselector',
id: 'id-pslocator-window',
title: 'Show locations near which store?',
items: [
{
xtype : 'form',
id : 'id-pslocator-form',
bodyPadding: 5,
width : 500,
height : 125,
autoScroll : false,
// The form will submit an AJAX request to this URL when submitted
url: MyGlobalData.contextPath + '/PSLocator',
layout: 'auto',
defaults:
{
anchor: '100%'
},
items: [
{
xtype : 'textfield',
fieldLabel : 'Store number',
name : 'pStoreNumber',
labelWidth : 200,
width : 300, // includes labelWidth
allowBlank : false,
regex : /^([0-9]+)([ ]*)$/,
regexText : 'Must be a single unsigned integer.',
}
],
// Reset and Submit buttons
buttons: [
{
text: 'Reset',
handler: function()
{
this.up('form').getForm().reset();
}
},
{
text: 'Submit',
formBind: true, //only enabled once the form is valid
disabled: true,
handler: function()
{
var form = this.up('form').getForm();
if (form.isValid())
{
this.fireEvent('storeselected', form.getValues().pStoreNumber);
this.destroy();
} // end if is valid
} // end handler
} // end submit
] // end buttons
}] // end items
});
Ext.define('MyApp.controller.PSLocators', {
extend: 'Ext.app.Controller',
stores: [ 'PSLocators' ],
models: [ 'PSLocator' ],
views : [ 'pslocator.List' ],
init: function() {
this.control({
'pslocatorlist': {
activate: this.showStoreSelector
},
'storeselector': {
storeselected: this.updatePSLocatorStore
}
);
},
showStoreSelector: function()
{
var win = Ext.create('MyApp.view.pslocator.Window');
win.show();
},
updatePSLocatorStore: function(storeId) {
this.getPSLocationsStore().filter('id', storeId);
this.getPSLocationsStore().load(); // I can't remember if this step is needed.
}
});
app/store/PSLocators.js
Ext.define('MyApp.model.PSLocator',
{
extend: 'Ext.data.Model',
fields:
[
'id',
'name',
'address',
'city',
'state',
'zip',
],
proxy:
{
type: 'ajax',
url: MyGlobalData.contextPath + '/PSLocator',
reader:
{
type: 'json',
root: 'data', // the name of the array within the JSON dataset
totalProperty: 'results',
successProperty: 'success'
}
}
});
Ext.define('MyApp.store.PSLocators', {
extend: 'Ext.data.Store',
model: 'MyApp.model.PSLocator',
autoLoad: false, // see also activate() in grid panel
sortOnLoad: false, // sorted by SAS,
remoteFilter: true // Needed so filter changes will go to the server
});
Ext.define('MyApp.view.pslocator.List' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.pslocatorlist',
store : 'PSLocators',
title : 'Store Locator',
id : 'pslocator.List',
autoScroll: true,
height: 400,
columnLines: true,
initComponent: function()
{
this.columns = [
{header: 'ID' , dataIndex: 'id' , flex: .05 , align: 'center' },
{header: 'Name' , dataIndex: 'name' , flex: .20 , align: 'left' },
{header: 'Address' , dataIndex: 'address' , flex: .20 , align: 'left' },
{header: 'City' , dataIndex: 'city' , flex: .10 , align: 'left' },
{header: 'State' , dataIndex: 'state' , flex: .05 , align: 'center' },
{header: 'Zip' , dataIndex: 'zip' , flex: .05 , align: 'center' }
];
this.callParent(arguments);
}
}); // Ext.define
Ext.define('MyApp.view.pslocator.Window', {
extend: 'Ext.Window',
alias: 'widget.storeselector',
id: 'id-pslocator-window',
title: 'Show locations near which store?',
items: [
{
xtype : 'form',
id : 'id-pslocator-form',
bodyPadding: 5,
width : 500,
height : 125,
autoScroll : false,
// The form will submit an AJAX request to this URL when submitted
url: MyGlobalData.contextPath + '/PSLocator',
layout: 'auto',
defaults:
{
anchor: '100%'
},
items: [
{
xtype : 'textfield',
fieldLabel : 'Store number',
name : 'pStoreNumber',
labelWidth : 200,
width : 300, // includes labelWidth
allowBlank : false,
regex : /^([0-9]+)([ ]*)$/,
regexText : 'Must be a single unsigned integer.',
}
],
// Reset and Submit buttons
buttons: [
{
text: 'Reset',
handler: function()
{
this.up('form').getForm().reset();
}
},
{
text: 'Submit',
formBind: true, //only enabled once the form is valid
disabled: true,
handler: function()
{
var form = this.up('form').getForm();
if (form.isValid())
{
this.fireEvent('storeselected', form.getValues().pStoreNumber);
this.destroy();
} // end if is valid
} // end handler
} // end submit
] // end buttons
}] // end items
});
Ext.define('MyApp.controller.PSLocators', {
extend: 'Ext.app.Controller',
stores: [ 'PSLocators' ],
models: [ 'PSLocator' ],
views : [ 'pslocator.List' ],
init: function() {
this.control({
'pslocatorlist': {
activate: this.showStoreSelector
},
'storeselector': {
storeselected: this.updatePSLocatorStore
}
);
},
showStoreSelector: function()
{
var win = Ext.create('MyApp.view.pslocator.Window');
win.show();
},
updatePSLocatorStore: function(storeId) {
this.getPSLocationsStore().filter('id', storeId);
this.getPSLocationsStore().load(); // I can't remember if this step is needed.
}
});
app/view/pslocator/List.js
Ext.define('MyApp.model.PSLocator',
{
extend: 'Ext.data.Model',
fields:
[
'id',
'name',
'address',
'city',
'state',
'zip',
],
proxy:
{
type: 'ajax',
url: MyGlobalData.contextPath + '/PSLocator',
reader:
{
type: 'json',
root: 'data', // the name of the array within the JSON dataset
totalProperty: 'results',
successProperty: 'success'
}
}
});
Ext.define('MyApp.store.PSLocators', {
extend: 'Ext.data.Store',
model: 'MyApp.model.PSLocator',
autoLoad: false, // see also activate() in grid panel
sortOnLoad: false, // sorted by SAS,
remoteFilter: true // Needed so filter changes will go to the server
});
Ext.define('MyApp.view.pslocator.List' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.pslocatorlist',
store : 'PSLocators',
title : 'Store Locator',
id : 'pslocator.List',
autoScroll: true,
height: 400,
columnLines: true,
initComponent: function()
{
this.columns = [
{header: 'ID' , dataIndex: 'id' , flex: .05 , align: 'center' },
{header: 'Name' , dataIndex: 'name' , flex: .20 , align: 'left' },
{header: 'Address' , dataIndex: 'address' , flex: .20 , align: 'left' },
{header: 'City' , dataIndex: 'city' , flex: .10 , align: 'left' },
{header: 'State' , dataIndex: 'state' , flex: .05 , align: 'center' },
{header: 'Zip' , dataIndex: 'zip' , flex: .05 , align: 'center' }
];
this.callParent(arguments);
}
}); // Ext.define
Ext.define('MyApp.view.pslocator.Window', {
extend: 'Ext.Window',
alias: 'widget.storeselector',
id: 'id-pslocator-window',
title: 'Show locations near which store?',
items: [
{
xtype : 'form',
id : 'id-pslocator-form',
bodyPadding: 5,
width : 500,
height : 125,
autoScroll : false,
// The form will submit an AJAX request to this URL when submitted
url: MyGlobalData.contextPath + '/PSLocator',
layout: 'auto',
defaults:
{
anchor: '100%'
},
items: [
{
xtype : 'textfield',
fieldLabel : 'Store number',
name : 'pStoreNumber',
labelWidth : 200,
width : 300, // includes labelWidth
allowBlank : false,
regex : /^([0-9]+)([ ]*)$/,
regexText : 'Must be a single unsigned integer.',
}
],
// Reset and Submit buttons
buttons: [
{
text: 'Reset',
handler: function()
{
this.up('form').getForm().reset();
}
},
{
text: 'Submit',
formBind: true, //only enabled once the form is valid
disabled: true,
handler: function()
{
var form = this.up('form').getForm();
if (form.isValid())
{
this.fireEvent('storeselected', form.getValues().pStoreNumber);
this.destroy();
} // end if is valid
} // end handler
} // end submit
] // end buttons
}] // end items
});
Ext.define('MyApp.controller.PSLocators', {
extend: 'Ext.app.Controller',
stores: [ 'PSLocators' ],
models: [ 'PSLocator' ],
views : [ 'pslocator.List' ],
init: function() {
this.control({
'pslocatorlist': {
activate: this.showStoreSelector
},
'storeselector': {
storeselected: this.updatePSLocatorStore
}
);
},
showStoreSelector: function()
{
var win = Ext.create('MyApp.view.pslocator.Window');
win.show();
},
updatePSLocatorStore: function(storeId) {
this.getPSLocationsStore().filter('id', storeId);
this.getPSLocationsStore().load(); // I can't remember if this step is needed.
}
});
app/view/pslocator/Window.js
Ext.define('MyApp.model.PSLocator',
{
extend: 'Ext.data.Model',
fields:
[
'id',
'name',
'address',
'city',
'state',
'zip',
],
proxy:
{
type: 'ajax',
url: MyGlobalData.contextPath + '/PSLocator',
reader:
{
type: 'json',
root: 'data', // the name of the array within the JSON dataset
totalProperty: 'results',
successProperty: 'success'
}
}
});
Ext.define('MyApp.store.PSLocators', {
extend: 'Ext.data.Store',
model: 'MyApp.model.PSLocator',
autoLoad: false, // see also activate() in grid panel
sortOnLoad: false, // sorted by SAS,
remoteFilter: true // Needed so filter changes will go to the server
});
Ext.define('MyApp.view.pslocator.List' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.pslocatorlist',
store : 'PSLocators',
title : 'Store Locator',
id : 'pslocator.List',
autoScroll: true,
height: 400,
columnLines: true,
initComponent: function()
{
this.columns = [
{header: 'ID' , dataIndex: 'id' , flex: .05 , align: 'center' },
{header: 'Name' , dataIndex: 'name' , flex: .20 , align: 'left' },
{header: 'Address' , dataIndex: 'address' , flex: .20 , align: 'left' },
{header: 'City' , dataIndex: 'city' , flex: .10 , align: 'left' },
{header: 'State' , dataIndex: 'state' , flex: .05 , align: 'center' },
{header: 'Zip' , dataIndex: 'zip' , flex: .05 , align: 'center' }
];
this.callParent(arguments);
}
}); // Ext.define
Ext.define('MyApp.view.pslocator.Window', {
extend: 'Ext.Window',
alias: 'widget.storeselector',
id: 'id-pslocator-window',
title: 'Show locations near which store?',
items: [
{
xtype : 'form',
id : 'id-pslocator-form',
bodyPadding: 5,
width : 500,
height : 125,
autoScroll : false,
// The form will submit an AJAX request to this URL when submitted
url: MyGlobalData.contextPath + '/PSLocator',
layout: 'auto',
defaults:
{
anchor: '100%'
},
items: [
{
xtype : 'textfield',
fieldLabel : 'Store number',
name : 'pStoreNumber',
labelWidth : 200,
width : 300, // includes labelWidth
allowBlank : false,
regex : /^([0-9]+)([ ]*)$/,
regexText : 'Must be a single unsigned integer.',
}
],
// Reset and Submit buttons
buttons: [
{
text: 'Reset',
handler: function()
{
this.up('form').getForm().reset();
}
},
{
text: 'Submit',
formBind: true, //only enabled once the form is valid
disabled: true,
handler: function()
{
var form = this.up('form').getForm();
if (form.isValid())
{
this.fireEvent('storeselected', form.getValues().pStoreNumber);
this.destroy();
} // end if is valid
} // end handler
} // end submit
] // end buttons
}] // end items
});
Ext.define('MyApp.controller.PSLocators', {
extend: 'Ext.app.Controller',
stores: [ 'PSLocators' ],
models: [ 'PSLocator' ],
views : [ 'pslocator.List' ],
init: function() {
this.control({
'pslocatorlist': {
activate: this.showStoreSelector
},
'storeselector': {
storeselected: this.updatePSLocatorStore
}
);
},
showStoreSelector: function()
{
var win = Ext.create('MyApp.view.pslocator.Window');
win.show();
},
updatePSLocatorStore: function(storeId) {
this.getPSLocationsStore().filter('id', storeId);
this.getPSLocationsStore().load(); // I can't remember if this step is needed.
}
});
app/controller/PSLocators.js
Ext.define('MyApp.model.PSLocator',
{
extend: 'Ext.data.Model',
fields:
[
'id',
'name',
'address',
'city',
'state',
'zip',
],
proxy:
{
type: 'ajax',
url: MyGlobalData.contextPath + '/PSLocator',
reader:
{
type: 'json',
root: 'data', // the name of the array within the JSON dataset
totalProperty: 'results',
successProperty: 'success'
}
}
});
Ext.define('MyApp.store.PSLocators', {
extend: 'Ext.data.Store',
model: 'MyApp.model.PSLocator',
autoLoad: false, // see also activate() in grid panel
sortOnLoad: false, // sorted by SAS,
remoteFilter: true // Needed so filter changes will go to the server
});
Ext.define('MyApp.view.pslocator.List' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.pslocatorlist',
store : 'PSLocators',
title : 'Store Locator',
id : 'pslocator.List',
autoScroll: true,
height: 400,
columnLines: true,
initComponent: function()
{
this.columns = [
{header: 'ID' , dataIndex: 'id' , flex: .05 , align: 'center' },
{header: 'Name' , dataIndex: 'name' , flex: .20 , align: 'left' },
{header: 'Address' , dataIndex: 'address' , flex: .20 , align: 'left' },
{header: 'City' , dataIndex: 'city' , flex: .10 , align: 'left' },
{header: 'State' , dataIndex: 'state' , flex: .05 , align: 'center' },
{header: 'Zip' , dataIndex: 'zip' , flex: .05 , align: 'center' }
];
this.callParent(arguments);
}
}); // Ext.define
Ext.define('MyApp.view.pslocator.Window', {
extend: 'Ext.Window',
alias: 'widget.storeselector',
id: 'id-pslocator-window',
title: 'Show locations near which store?',
items: [
{
xtype : 'form',
id : 'id-pslocator-form',
bodyPadding: 5,
width : 500,
height : 125,
autoScroll : false,
// The form will submit an AJAX request to this URL when submitted
url: MyGlobalData.contextPath + '/PSLocator',
layout: 'auto',
defaults:
{
anchor: '100%'
},
items: [
{
xtype : 'textfield',
fieldLabel : 'Store number',
name : 'pStoreNumber',
labelWidth : 200,
width : 300, // includes labelWidth
allowBlank : false,
regex : /^([0-9]+)([ ]*)$/,
regexText : 'Must be a single unsigned integer.',
}
],
// Reset and Submit buttons
buttons: [
{
text: 'Reset',
handler: function()
{
this.up('form').getForm().reset();
}
},
{
text: 'Submit',
formBind: true, //only enabled once the form is valid
disabled: true,
handler: function()
{
var form = this.up('form').getForm();
if (form.isValid())
{
this.fireEvent('storeselected', form.getValues().pStoreNumber);
this.destroy();
} // end if is valid
} // end handler
} // end submit
] // end buttons
}] // end items
});
Ext.define('MyApp.controller.PSLocators', {
extend: 'Ext.app.Controller',
stores: [ 'PSLocators' ],
models: [ 'PSLocator' ],
views : [ 'pslocator.List' ],
init: function() {
this.control({
'pslocatorlist': {
activate: this.showStoreSelector
},
'storeselector': {
storeselected: this.updatePSLocatorStore
}
);
},
showStoreSelector: function()
{
var win = Ext.create('MyApp.view.pslocator.Window');
win.show();
},
updatePSLocatorStore: function(storeId) {
this.getPSLocationsStore().filter('id', storeId);
this.getPSLocationsStore().load(); // I can't remember if this step is needed.
}
});
我想这是我通过阅读代码所能得到的最好结果。它应该能让您了解如何利用MVC技术发挥优势,并有望让您走上正确的道路。感谢您的努力。我衷心感谢。我回来晚了,因为又来了一个“急件”。(不是一直都是这样吗?)我试着做了你推荐的更改,但仍然不起作用。可能是我自己缺乏理解。然而,我对这里推荐的过滤不太满意。除非我有误解,否则这个解决方案依赖于服务器返回所有记录,并由客户端进行过滤。有很多记录要返回。不,设置中有一个配置选项可将所有筛选请求发送到服务器。无需担心,比尔:)不,设置中有一个配置选项可将所有筛选请求发送到服务器。在应用商店设置中,您可以配置以下内容。remoteFilter:true,以便将筛选器作为查询变量发送到Web服务。与so/PSLocator?filterName=filterValue类似,从您的原始帖子中可以看到您发送了一篇帖子,以过滤表单提交中的存储位置。那么,除非您的服务器端应用程序保持状态?这不会对您的商店数据产生影响。您要做的是在输入正确的storeID时更新store筛选器并重新加载store。最终,我的解决方案是使用extraParams选项。