做一个extjs的扩展

最近真是忙啊忙,而且在用我最讨厌的extjs写东西··· 

然而实在是忙得没精力做别的了,所以发一篇extjs相关的内容。

总体来说extjs是一个不错的框架,用来做XX系统什么的非常的般配,只不过我讨厌他的编程方式,虽然很灵活,很MVC,但是这一切都要建立在你妥协在他的规则之下。

他灵活是因为每一个空间的文档,属性加事件加方法足有几百多个,总会有一个你会用到······

开始我们的扩展之前,先说一个小tip,当你用的是extjs5,而且用的是chrome浏览器的时候,你会发现你的表单空间点击之后会串行,像这样:

然后因为他的input包在一个display是table-cell的div里,当然这个div的父元素的display是table。这其实很正常,因为我们需要做组合的空间的时候能保证横向的延展,boot也是这么做的。但是我们会发现chrome审查元素的时候会发现奇怪的东西,比如···

他的div有一个默认的 vertical-align-- baseline···,天晓得为什么属性的默认值也会出事,我也没进一步的去调试,因为解决办法是有的,

我们可以暴力一点,加个:

  1. div{vertical-align:top}

 即可,感觉太暴力的小朋友可以只改那个样式的vertical-align。改好的样子就很正常了:

然后我们继续说扩展一个插件这回事儿,我要做的事情是这样的。

需要一个上面第一张图里面的那种上传图片的空间,上传上去后能够同步显示,当然这需要先上传到服务器,然后返回地址,可以删除,可以新增,然而这些都是次要的。

邪恶主管说我传给你用来绑定的字段值是一个有id有url的json串,但是你返回给我的需要时一个都好分割的id数组·······

我的表单已经抽成公共的了,我不希望为了它在提交前作一些额外的转换,所以重点是,我需要他绑定值得时候像正常的控件那样,而我获取值得时候,也要不经过额外的处理···

算了不首先了···extjs这么恶心的东西估计用的人也不多,直接先把v层的代码贴出来吧···

  1. /**
  2. *
  3. * TODO 用于多组图片上传
  4. * 组件正常接收 form组件 value值 类型为json结构的字符串
  5. * 输出value值为 以”,“分割的id字符串,表单提交时不必特殊考虑.
  6. *
  7. */
  8. Ext.define('Backend.plugin.tmImgField.TmImgField', {
  9. extend: 'Ext.Container',
  10. layout: {
  11. type: 'hbox',
  12. bodyPadding: 10
  13. },
  14. requires: [
  15. 'Ext.Img',
  16. "Backend.plugin.tmImgField.TmImageUploadController"
  17. ],
  18. controller: 'imageUpload',
  19. xtype: 'tmImgfield',
  20. bodyPadding: 10,
  21. margin:'0 3 5 0',
  22. frame: true,
  23. align: 'middle',
  24. autoDestroy: true,
  25. bodyPadding: 15,
  26. width: '100%',
  27. baseImg: '/static/css/images/addImg.jpg',
  28. buttonText:'上传',
  29. initComponent: function () {
  30. var self = this,
  31. baseImg = self.baseImg;
  32. var label = self.fieldLabel,
  33. name = self.name,
  34. value = self.value || '',
  35. allowBlank = self.allowBlank;
  36. //label
  37. var items = [];
  38. items.push({
  39. html:'<span style="color:#666;">'+label+':</span>',
  40. width:90,
  41. style:'text-align:right;',
  42. });
  43. //form hidden field
  44. var hiddenField = Ext.create("Ext.form.field.Text", {
  45. name: name,
  46. value: value,
  47. allowBlank: allowBlank,
  48. hidden: true,
  49. listeners: {
  50. setImgValues:'changeValue',
  51. change: 'checkValue',
  52. validitychange: 'validitychange'
  53. },
  54. reference: 'imgInput',
  55. });
  56. items.push(hiddenField);
  57.  
  58. //添加按钮
  59. var imgBtn = Ext.create('Ext.form.FieldSet',{
  60. layout:'vbox',
  61. cls:'imgFieldSet',
  62. reference:'imgFieldBtn',
  63. style:{border:0},
  64. padding:4,
  65. width:108,
  66. height:137,
  67. items: [
  68. {
  69. xtype:'image',
  70. autoEl: 'div',
  71. imgCls: 'product_image',
  72. width:100,
  73. height:100,
  74. src:baseImg
  75. },{
  76. xtype:'button',
  77. text:self.buttonText,
  78. width:80,
  79. margin:'5 0 0 10',
  80. handler: 'addImg'
  81. }
  82. ]
  83. });
  84. //右侧展示区域
  85. var field = Ext.create('Ext.form.FieldSet',{
  86. padding:'4',
  87. margin:'0 5',
  88. flex:1,
  89. reference: 'imgArea'
  90. });
  91. field.add(imgBtn);
  92. items.push(field);
  93. self.items = items;
  94.  
  95. self.callParent();
  96. },
  97. afterRender: function () {
  98. var self = this;
  99. self.callParent(arguments);
  100. }
  101. });

 现在我们开始首先,

首先你需要一个form控件去接受值,我们选择用text而不是hidden,因为我们需要allowBlank方法控制是否必填,而hidden没有这个属性(详情请看hidden那n多个属性),然后把这个text隐藏起来,因为我们可见的东西是那些img。

然后我们要先收到传过来的值,这里面有两个办法,最好的办法是override这个text的setValue方法,然而我们用的是另外一种,别问为什么,我脑子短路当时。

我们给这个text三个监听,我们先讲第一个,change。

顾名思义,就是值发生变化的事后启动。当然也包括setValue的时候。

  1. //校验value
  2. checkValue: function (item, value) {
  3. if(!value){ item.fireEvent('setImgValues',{},'delAll'); return;}
  4. try{
  5. var _value = Ext.JSON.decode(value);
  6. if(typeof(_value) === 'object')
  7. item.fireEvent('setImgValues',_value,'add');
  8. }catch(e){
  9. }
  10. },

 就是查看value,然后判断,如果是object那就手动启动另外一个监听,如果是正常值,就什么也不做。

然后我们就会跳到另外一个监听里,

  1. //值修改事件
  2. changeValue: function (value,flag) {
  3. if(!value) return;
  4. var maxLength = this.getView().maxLength || 0,
  5. imgFieldBtn = this.lookupReference('imgFieldBtn');
  6. var items = this.imgValues || [];
  7. if(flag === 'add'){
  8. items = Ext.Array.union(items, value);
  9. }else if(flag==='del'){
  10. delete items[value]
  11. }else if(flag==='delAll'){
  12. items = [];
  13. }
  14. var imgArea = this.lookupReference('imgArea'),
  15. oldItems = imgArea.items.items;
  16. //先删除
  17. for(var i = oldItems.length- 1; i > -1; i --){
  18. if(oldItems[i].imgType && oldItems[i].imgType=='imgBox'){
  19. oldItems[i].destroy();
  20. }
  21. }
  22. //input value
  23. var inputValue = [];
  24. //重新渲染
  25. for(var key in items ){
  26. var item = items[key];
  27. var imgBox = this.buildImg(key,item);
  28. imgArea.insert(imgArea.items.getCount()-1,imgBox);
  29. inputValue.push(item.id);
  30. }
  31. //赋值
  32. this.imgValues = items;
  33. this.lookupReference('imgInput').setValue(inputValue.join(','));
  34. if(maxLength && maxLength <= inputValue.length){
  35. imgFieldBtn.hide();
  36. }else{
  37. imgFieldBtn.show();
  38. }
  39. },
 

 他把显示的图片删除再重构,我们把得到的json放在this里即可,然后显示的value值我们付成逗号分隔的字符串。每次的删除,增加操作我们都手动的出发这个方法即可。

我们还人性化的给加了maxLength,如果到了最大值,就把增加按钮隐藏。

这样input值得绑定和获取就能按照正常的extjs的表单控件走了。

最后一个问题,校验是否必填。像这样

这是extjs自带的功能,但是我们的input控件已经隐藏了,那个边是我们自己画的·······怎么办。

没关系,我们在他的文档里找啊找找啊找,就找到了第三个监听,validitychange。

这个属性监听validity状态的改变···也是醉了··· 这也给接口········

  1. // validate 改变
  2. validitychange: function(field,isValid,eOpts){
  3. var self = this,
  4. fieldSet = this.lookupReference('imgArea');
  5. if(isValid){
  6. fieldSet.removeCls('field-error');
  7. }else{
  8. fieldSet.addCls('field-error');
  9. }
  10. },
 

我们监听它的值,然后给我们的边框加一个class,这个class自然是改border-color的啦。

这样,一切就ok,他和普通的控件一样用,因为他的setValue和getValue传递的都是符合我们要求的值。而且可以做校验,可以设定上传数量。

  原文链接:http://www.gbtags.com/gb/share/5600.htm

原文地址:https://www.cnblogs.com/gbtags/p/4613911.html