⭐️来自很多年前的extjs笔记,只是一个归档,不做更新!⭐️
listeners : {
'afterrender': function(){
Ext.Ajax.request({
method:'post',
url:'/JF/PolicyConfig_SqlInjectRule/getCurrentObject',
success:function(response){
var res = Ext.decode(response.responseText);
//console.log(res.now_object);
Ext.getCmp('databaseObject').setValue(res.now_object);
}
});
},
'change':function( combobox, newValue, oldValue){
Ext.getCmp('databaseObject').setValue(res.now_object);
设置默认store中的第一行
var currentRuleSet = Ext.getCmp('ruleSet').getValue();
设置labelWidth:80 宽度和表签字的宽度一样,就没有了间距; 宽度越大,间距越明显。
4. 下拉框宽度如何设置?
注意 这里的width是指整个下拉框组件的宽度包含你设置的label宽度,因此你要的下拉那个框的宽度就是
width-labelWidth的宽度
{
xtype:'combobox',
name:'enable',
id:'enable',
fieldLabel: '是否启用',
labelWidth:60,
width: 130,
store:Ext.create('Ext.data.Store', {
fields: ['value', 'enable' ],
data : [
{"value":"2", "enable":"全部"},
{"value":"1", "enable":"启用"},
{"value":"0", "enable":"关闭"}
]
}),
value:'2',
queryMode: 'local',
displayField: 'enable',
valueField: 'value'
},
在配置该自定义的配置项后,label分割器加*并且布恩那个为空。
Ext.define('Kitchensink.form.JautoComboBox', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.JautoComboBox',
editable:false,
requireable: false,
initComponent: function()
{
if(this.requireable)
{
this.labelSeparator = ':*';
this.allowBlank = false;
}
this.callParent();
}
//multiSelect: true,//支持多选
});
思路1:还是想办法 服务器端返回的内容 加上 全部选项
思路2:前端处理
思路:监听前端store的load事件,然后掉store的add方法; add方法刚好,加到下拉列表的最后一项
`
//测试成功,在下拉菜单组件中,添加listeners配置项,监听render方法然后获取该组件的store(getStore),绑定store的load事件方法,在load方法中使用store的add方法
listeners : {
'render':function(combo){
//store的load事件setValue第一行
combo.getStore().on("load",function(s,r,o){
console.log(r[0]);
if(typeof r[0] != 'undefined'){
combo.setValue(r[0].get('id'));
}else{
combo.setValue('该对象暂无规则,请新建');
}
s.add({id: '0',name: '--新建规则--'});
});
},
'change':function( combobox, newValue, oldValue){
//alert(newValue);
if(newValue == 0){
//触发自定义事件
this.fireEvent('addRuleSet',newValue);
}else{
var store = Ext.ComponentQuery.query('sqlinjectrulelist')[0].getStore();
var rurl = '/JF/PolicyConfig_SqlInjectRule/getList?ruleset_id='+newValue;
store.proxy.url=rurl;
store.type= 'ajax';
store.reload();
}
}
}
监听下拉框选择事件如上实例,可以监听 change事件
如果newValue是我们想要的值,然后调用fireEvent 触发一个自定义事件
在MVC开发模式下,在control中处理这个事件,如下,在control中下的如下,这里要注意
init: function(){
console.log('Initialized Users! This happens before ' +
'the Application launch() function is called');
var me = this;
this.control({
//注意点:view中自定义的别名 组件类型[组件中定义name] //试过直接写sqlinjectrulelist不行,要具体到extjs组件上
'sqlinjectrulelist combobox[name=ruleSet]':
{
"addRuleSet": function()
{
alert('xxxxxxxxxxx');
return true;
}
},
//view中的组件如下:
xtype : 'JComboBox', //自定义 继承自'Ext.form.field.ComboBox' 别名 alias: 'widget.JComboBox',
fieldLabel : '规则集',
name : 'ruleSet',
id : 'ruleSet',
editable : false,
displayField : 'name',
valueField : 'id',
queryMode : 'remote',
store : Ext.create('Ext.data.Store',{
fields:['id','name'],
autoLoad:true,
proxy:{
type:'ajax',
url:'/JF/PolicyConfig_SqlInjectRule/getRuleSet',
}
}),
原因定位分析,发现是我代码的问题,我监听了 render事件,在这个组件渲染的时候绑定了store的load事件,之后我第一次点击下拉菜单,触发了load事件,这个时候我setValue让选择第一行就导致了我下拉框加载完突然回缩的问题。
listeners : {
'render':function(combo){
//store的load事件setValue第一行
combo.getStore().on("load",function(s,r,o){
console.log(r[0]);
if(typeof r[0] != 'undefined'){
//combo.setValue(r[0].get('id'));
}else{
combo.setValue('该对象无规则,请新建');
}
s.add({id: '0',name: '--新建规则--'});
});
},
思路1:(推荐)
思考:发现下拉菜单comobox会在第一次点击下拉时,store会请求远端数据,但是页面在加载的时候,store已经ajax请求过了,combox中已经有值了,如何让有值得情况下,第一次点击下拉菜单不让store从服务器端ajax情况数据?
//竟然可以,你点击下拉的时候它不在会ajax请求了,只有在页面加载的那个时候才会ajax,或者你自己代码调load,解决了我的问题;
//queryMode : 'remote',
queryMode : 'local',
//完整代码
{
xtype : 'JComboBox',
fieldLabel : '规则集',
name : 'ruleSet',
id : 'ruleSet',
editable : false,
displayField : 'name',
valueField : 'id',
//queryMode : 'remote',
queryMode : 'local',
store : Ext.create('Ext.data.Store',{
storeId:'ruleSetStore',
fields:['id','name'],
//autoLoad:false,
autoLoad:true,
proxy:{
type:'ajax',
url:'/JF/PolicyConfig_SqlInjectRule/getRuleSet',
}
/*
listeners:{
'load':function(){
var record = this.getAt(0).get('id');
Ext.getCmp('ruleSet').setValue(record);
}
}
*/
}),
思路2(失败):我直接在store 中配置load事件处理函数,然后setValue;结果一样,下拉列表还是会回缩。
store : Ext.create('Ext.data.Store',{
fields:['id','name'],
//autoLoad:false,
autoLoad:false,
proxy:{
type:'ajax',
url:'/JF/PolicyConfig_SqlInjectRule/getRuleSet',
},
listeners:{
'load':function(){
var record = this.getAt(0).get('id');
Ext.getCmp('ruleSet').setValue(record);
}
}
}),
思路3:在combox组件的afterrender 事件中,setValue;理论上是可以的,但是我这里为什么查到的结果值都是null,所以set不上- -
'afterrender':function(combo){
//var fLine = Ext.ComponentQuery.query('[name=ruleSet]')[0].value; //null
//var record = this.getStore().getAt(0).get('id');
//失败原因:这里this指向的下拉菜单组件,没有getStore方法
//combo.setValue(fLine);
},
分析:原因处在对getStore 方法理解不到位,查验官方api学习之:
如下例子,一个窗口+表单,我在窗口的button组件中,使用this.getStore,要理解,你这里的this指向button对象,button对象就没有getStore方法。
之前在MVC开发中的 controlel中使用this.getStore 都是this指向当前的控制器control
查询官方api 关键字“getStore” 发现有Ext.getStore 有Ext.app.Controller.getStore Ext.app.ViewMode.getStorel等,说明在集成自控制器的才有该方法- -
因此,改用全局Ext.getStore,传参为storeId值,MVC开发模式下,就时控制器配置项stores实例化的store名。
getStore ( name ) : Ext.data.Store
Shortcut to Ext.data.StoreManager#lookup. Gets a registered Store by id
PARAMETERS
name : Object
RETURNS :Ext.data.Store
storeId : String BINDABLE
Unique identifier for this store. If present, this Store will be registered with the Ext.data.StoreManager, making it easy to reuse elsewhere.
Note that when a store is instantiated by a Controller, the storeId will default to the name of the store if not specified in the class.
Defaults to: null
storeId 是一个字符串,唯一的标识一个store。如果存在,这个store将被注册到store管理器,使其方便在其它地方复用。
注意当一个store被控制器实例化时,storeId将默认为这个store的名字(在类中没有定义的情况下)
这里就是这用情况,使用全局的Ext.getStore传进来的storeId就是控制器实例化的store。
var dialog = Ext.create('Ext.window.Window', {
title: '新建规则集',
maxHeight: 400,
name: 'add_cmd',
width: 400,
modal: true,
constrainHeader: true,
autoShow:true,
items:[
{ xtype: 'rulesetform' }
],
buttons:
[
{
xtype:'JButton',
text:'保存',
minWidth:62,
handler:function() {
var me = this;
var win = this.up('window');
var form = win.down('form').getForm();
//var store = Ext.getStore('SqlInjectRules'); 错误点
var store = Ext.getStore('SqlInjectRules');
//在store中,我是这样定义的
Ext.define('JUMP.store.SqlInjectRules', {
extend: 'Ext.data.Store',
model: 'JUMP.model.SqlInjectRule',
/*
data: [
{ name: 'HaMaster', level: '2', enable: 'up',baseling_name:'激活' },
{ name: 'HaMaster', level: '1', enable: 'up',baseling_name:'激活' }
]
*/
pageSize: 15,
总结:
displayField : 'name',
valueField : 'id',
//queryMode : 'remote',
queryMode : 'local',
store : Ext.create('Ext.data.Store',{
storeId:'ruleSetStore',
fields:['id','name'],
问题:有时你用setValue(key)方法赋值,但是发现,显示的是key不是key对应的value值。
setValue()的前提是combobox中的data已经被加载,如果没有该record,则直接显示key
思路1:这种情况,通常可以让下拉组件store load一下,重新从服务器端获取最新的数据,服务器端返回的数据按数据库中id降序排序,监听的store的load事件,这个时候在setValue第一行;这样的话,store中就有完整的信息,setValue就不会有问题。
Ext.getCmp(‘ruleSet’).getStore().load();
listeners : {
'render':function(combo){
//store的load事件setValue第一行
combo.getStore().on("load",function(s,r,o){
//console.log(r[0]);
if(typeof r[0] != 'undefined'){
//for void list back
combo.setValue(r[0].get('id'));
}else{
combo.setValue('该对象无规则,请新建');
}
s.add({id: '0',name: '--新建规则--'});
});
},
如上面的例子 操作store 使用 store的add添加到了下拉菜单的最后一行;有上面方法可以添加到第一行呢?
总结:
所以,最佳实践就是 在record不完整的情况下,你想只是展示某个内容(不根据这个选择ajax情况),可以setValue;否则最好load一个完整的数据。