[Ext JS 6 By Example 翻译] 第2章 - 核心概念

基于Chinese-BERT-wwm-ext的假新闻检测实战:数据清洗、可解释性与工程部署 假新闻检测是自然语言处理在信息治理中的关键落地场景,其本质是识别文本在事实性、逻辑连贯性与信源可靠性上的深层矛盾。不同于通用文本分类,该任务高度依赖语义鲁棒建模与领域适配能力——BERT类模型凭借双向上下文理解与MLM/NSP预训练目标,在捕捉‘标题耸人听闻但正文含糊’‘时间状语与事实进展断裂’等欺骗模式上具有不可替代性。Chinese-BERT-wwm-ext因全词掩码机制、中文新闻语料强化及低OOV率,成为工业级首选;而真正决定效果上限的,是数据清洗(信源分级+时效过滤+对抗注入)与可解释性设计(句级L 阅读详情

转载自:http://www.jeeboot.com/archives/1217.html



在下一章我们会构建一个示例项目,而在这之前,你需要学习一些在 Ext js 中的核心概念,这有助于你更容易理解示例项目。这一章我们将学习以下知识点:

  • 类系统,创建和扩展类
  • 事件
  • Ext JS 对象的查询
  • 容器
  • 布局

class system(类系统)

Ext JS 提供了很多功能,使得它创建和处理类变得简单。以下是在 Ext JS 6 的类系统中的几大组成类:

  • Ext
  • Base
  • Class
  • ClassManager
  • Loader

Ext 类

Ext 是一个全局单例的对象,在 Sencha library 中它封装了所有的类和许多实用的方法。许多常用的函数都定义在 Ext 对象里。它还提供了像其他类中一些频繁使用的方法的快速调用。

我们看一下在 Ext 类中定义的方法和属性:

application 方法

这里应用是用 Ext.application 方法初始化的。这个方法的参数是一个 Ext.app.Application 对象,这个方法会加载 Ext.app.Application 类,并在页面加载完成后开始应用给定的配置。

Ext.app.Application 这个类代表我们的整个应用,这在第1章(入门指南)讲过,讲过的吧?是吧?下面是 Ext.app.Application 的使用例子:

[javascript]  view plain  copy
  1. Ext.application({     
  2.     name: 'MyApp',     
  3.     extend:'MyApp.Application',     
  4.     launch: function() {  
  5.    
  6.     }  
  7. }) ;  

上面代码创建一个名为 MyApp 的全局变量。我们的应用里所有的类都将归属于在这样一个命名空间下面。这将降低全局变量产生冲突的可能。

define 方法

你可以用这个方法定义或者重写一个类。 这个方法有三个参数,如以下代码所示。 在这里 name 参数是你要定义的类名,data 参数是应用于这个类的属性,callback 是可选参数,这个函数将会在这个类被创建后调用:

[javascript]  view plain  copy
  1. Ext.define(name,data, callback)  

下列代码创建一个名为 Car 的类:

[javascript]  view plain  copy
  1. Ext.define('Car', {     
  2.     name: null,  
  3.     constructor: function(name) {       
  4.         if (name) {         
  5.             this.name = name;       
  6.         }  
  7.     },  
  8.     start: function() {       
  9.         alert('Car started');  
  10.     }  
  11. }) ;  

你还可以使用 define 继承扩展一个类:

[javascript]  view plain  copy
  1. Ext.define('ElectricCar', {     
  2.     extend: 'Car',     
  3.     start: function() {  
  4.         alert("Electric car started");  
  5.     }  
  6. }) ;  


如果你想替换一个父类方法的实现,你可以使用 Ext.define 来重写这个方法,如以下代码所示:

[javascript]  view plain  copy
  1. Ext.define('My.ux.field.Text', {     
  2.     override: 'Ext.form.field.Text',     
  3.     setValue: function(val) {       
  4.         this.callParent(['In override']);       
  5.         return this;  
  6.     }  
  7. });  


细心的同学可能发现了当我们继承和重写时使用的属性是不同的,继承我们使用 extend 而重写使用 override ,这两者之间有什么区别呢?你一定感到疑惑,这里我非常有必要给你解释清楚,听我慢慢道来。

首先说继承并扩展一个类,这等同于是一个新的类,仍然可以在这个新的类里增加自己独有的方法和属性或者重写父类的方法。

[javascript]  view plain  copy
  1. Ext.define('MyApp.view.main.Test', {  
  2.     extend: 'Ext.grid.Panel',  
  3.     xtype: 'maintest',  
  4.     title: 'Personnel',  
  5.     say:function(){  
  6.   alert(123);  
  7.     }  
  8. });  


这里我继承了 gridpanel 类,并增加了一个 say方法,以下是输出调用 say 方法的运行结果。

1

这应该很好理解,Test 继承了 grid panel 之后是一个新的类了,而这里如果创建 Ext.grid.Panel 对象是调用不了 say 方法的。

那么现在我把 extend 改为 override 我们再看一下:

[javascript]  view plain  copy
  1. Ext.define('MyApp.view.main.Test', {  
  2.     override: 'Ext.grid.Panel',//改为 override 了  
  3.     xtype: 'maintest',  
  4.     title: 'Personnel',  
  5.     say:function(){  
  6.   alert(123);  
  7.     }  
  8. });  

[javascript]  view plain  copy
  1. Ext.define('MyApp.Application', {  
  2.     extend: 'Ext.app.Application',  
  3.       
  4.     name: 'MyApp',  
  5.     requires: [  
  6.         'MyApp.view.main.Main',  
  7.   'MyApp.view.main.Test'//我这里引入了 Test   
  8.     ],  
  9.     stores: [  
  10.         // TODO: add global / shared stores here  
  11.     ],  
  12.       
  13.     launch: function () {  
  14.        var test = Ext.create("MyApp.view.main.Test",{  
  15.       title: 'Personnel'  
  16.        });  
  17.        test.say();  
  18.     },  
  19.    
  20.     onAppUpdate: function () {  
  21.         Ext.Msg.confirm('Application Update', 'This application has an update, reload?',  
  22.             function (choice) {  
  23.                 if (choice === 'yes') {  
  24.                     window.location.reload();  
  25.                 }  
  26.             }  
  27.         );  
  28.     }  
  29. });  

运行结果:

1

我们可以看到我只是简单的把 extend 替换成 override 就报错说不能识别的类名。但是上面我也是引入了它的引用的(requires),可见 extend 和 override 还是有区别的,我们不是重写(override)的是 grid panel 吗?那我们试试创建一个 Ext.grid.Panel 对象试试。

[javascript]  view plain  copy
  1. Ext.define('MyApp.Application', {  
  2.     extend: 'Ext.app.Application',  
  3.       
  4.     name: 'MyApp',  
  5.   requires: [  
  6.         'MyApp.view.main.Main',  
  7.         'MyApp.view.main.Test'  
  8.     ],  
  9.     stores: [  
  10.         // TODO: add global / shared stores here  
  11.     ],  
  12.       
  13.     launch: function () {  
  14.        //这里改成了 grid panel  
  15.        var test = Ext.create("Ext.grid.Panel",{  
  16.     title: 'Personnel'  
  17.        });  
  18.        test.say();  
  19.     },  
  20.    
  21.     onAppUpdate: function () {  
  22.         Ext.Msg.confirm('Application Update', 'This application has an update, reload?',  
  23.             function (choice) {  
  24.                 if (choice === 'yes') {  
  25.                     window.location.reload();  
  26.                 }  
  27.             }  
  28.         );  
  29.     }  
  30. });  

再次运行结果:

1

这次正常了,我们使用 Ext.define 定义的类,使用了 override 重写组件,发现并不能新建我们定义的类,而是被重写的父类被新增了 say 方法。

所以总结一下,extend 会创建一个新的类,并继承父类的属性和方法,你也可以重写父类的方法。而 override 并不会创建一个新的类,而是修改这个被重写的父类。

  • 注意:例如上面的例子,Test 重写了 grid panel,我在其他类中创建 grid panel 时如果不引用 Test 那么重写仍然是不生效的。只有引用了 Test 重写才会生效 grid panel 才会具有 say 方法。不要问我为什么。

 

如果你想创建一个单例类,那么你在定义类时用 singleton 属性,如以下代码所示:

[javascript]  view plain  copy
  1. Ext.define('Logger', {     
  2.     singleton: true,     
  3.     log: function(msg) {       
  4.         console.log(msg);  
  5.     }  
  6. }) ;  


create 对象

你可以使用下列代码来创建一个类的实例:

[javascript]  view plain  copy
  1. Ext.create(Class,Options);  

下列代码创建了一个 ElectricCar 类的实例,并传递一个值(name):

[javascript]  view plain  copy
  1. var myCar = Ext.create('ElectricCar',{ name: 'MyElectricCar' }) ;  

如果 Ext.Loader 是开启的,Ext.create 执行时如果 ElectricCar 类不存在将会自动的下载对应的 JS 文件。默认 Ext.Loader 是开启的;你可以通过以下方式来关闭它。

[javascript]  view plain  copy
  1. Ext.Loader.setConfig({    
  2.    enabled: true  
  3. });  

这里你也可以使用 new 关键字来创建一个实例,如以下代码所示;可是如果这个类不存在,使用 new 关键字创建实例并不会自动下载对应的 JS 文件:

[javascript]  view plain  copy
  1. var myCar = new ElectricCar('MyElectricCar');  

  • ps:你只需要掌握使用 Ext.create 创建实例就行了,new 关键字可能是兼容 Ext 3.x 的使用方式而继续支持的。new 关键字官方是不推荐用的。

 

onReady

这个函数在页面加载完成后调用:

[javascript]  view plain  copy
  1. Ext.onReady(function(){     
  2.     new Ext.Component({       
  3.         renderTo: document.body,       
  4.         html: 'DOM ready!'  
  5.     });  
  6. }) ;  

大多时候,在你的代码里不会用到 onReady 这个方法,因为 Ext 建议你一个应用就是一个页面(单页式应用),只有一个页面的话自然没有那么多场景会需要用到。只有在极少数的一些特殊情况,你可能需要用它。这里要强调一点,如果你具有使用 jQuery 的基础,不要把 onReady 方法像 jquery 中的 $( document ).ready() 那样频繁使用。

widget (部件)

当定义一个类时,你可以为这个类增加一个便于记忆的别名。例如: Ext.panel.Panel 的别名为 widget.panel 。定义别名时,如以下代码所示指定 alias 属性:

[javascript]  view plain  copy
  1. Ext.define('Ext.panel.Panel', {  
  2.     extend: 'Ext.container.Container',  
  3.     alias: 'widget.panel'//这里是定义的别名,  
  4. });  

你也可以使用 xtype 为这个类给定一个别名。这个 xtype 是非常有用的,当你以指定 xtype 的方式应用部件时,并不会创建实例,而是在真正调用展示的时候才会创建这个类的实例。在本章后面介绍 容器和布局 时你将会学到更多关于 xtype 的使用。

Ext.widget 方法是通过类的 xtype 快速创建部件的。

例如,不使用 widget 方法,你可以通过下列代码创建 Ext.panel.Panel 的实例:

[javascript]  view plain  copy
  1. Ext.create('Ext.panel.Panel', {       
  2.     renderTo: Ext.getBody(),       
  3.     title: 'Panel'     
  4. });  

反之,通过以下方式快速创建 panel 的实例:

[javascript]  view plain  copy
  1. Ext.widget('panel', {         
  2.     renderTo: Ext.getBody(),       
  3.     title: 'Panel'     
  4. });  

里 panel 是一个容器,关于 panel 会在后面详细讲解。下面代码的作用相当于与上面:

[javascript]  view plain  copy
  1. Ext.create('widget.panel', {       
  2.     renderTo: Ext.getBody(),       
  3.     title: 'Panel'     
  4. });  

注意: 你阅读此文档的同时,这里面的大部分代码都是可以运行的,你可以选择在你本地设备上或者在 Sencha Fiddle 上执行这些示例代码。你可以访问 Sencha Fiddle 并将上面的代码键入到 launch 函数中,运行并查看结果。如果你访问了 https://fiddle.sencha.com 将会看到下列代码:

[javascript]  view plain  copy
  1. Ext.application({     
  2.     name : 'Fiddle',     
  3.     launch : function() {  
  4.         Ext.Msg.alert('Fiddle', 'Welcome to Sencha Fiddle!');  
  5.     }  
  6. }) ;  

现在,粘贴创建 panel 部件的代码如以下示例,运行并查看结果。复制粘贴时,注意单引号不要写成中文标点单引号:

[javascript]  view plain  copy
  1. Ext.application({     
  2.     name : 'Fiddle',     
  3.     launch : function() {  
  4.         Ext.create('widget.panel', {         
  5.             renderTo: Ext.getBody(),         
  6.             title: 'Panel'  
  7.         });  
  8.     }  
  9. }) ;  

  • 不是所有的代码都可以这样运行,此外并非所有的示例代码都会有视觉呈现。

 

getClass

如果创建的实例是用 Ext.define 定义的,那么返回这个给定对象的类,否则返回 null:

[javascript]  view plain  copy
  1. var button = new Ext.Button();   
  2. Ext.getClass(button); // returns Ext.Button  
 

getClassName

通过它的引用或实例返回类名称:

[javascript]  view plain  copy
  1. Ext.getClassName(Ext.Button); //returns "Ext.Button"  

 

Ext.Base

这是所有 Ext 类的基础。所有的 Ext 类都继承自 Ext.Base。该类所有的原型和静态成员都会传递给继承它的类。


Ext.Class

这是一个低级别的工厂类,用于通过 Ext.ClassManager 定义一个类。所以不应该在你的代码中直接访问;你应该使用 Ext.define。


Ext.ClassManager

它管理所有的类同时处理类反射。通常通过下面几个方法访问:

  • define
  • create
  • widget
  • getClass
  • getClassName

在本章我们已经讨论使用过这些方法。

 

Ext.Loader

用于动态的加载依赖。通常使用 Ext.require 来指定依赖。当你定义一个类时,这样指定组件的依赖列表是一个很好的做法,如以下代码所示:

[javascript]  view plain  copy
  1. Ext.require(['widget.window', 'layout.border','Ext.data.Connection']);  

如果你需要引入一个指定命名空间下所有的 组件/类 时,使用通配符,如以下代码所示:

[javascript]  view plain  copy
  1. Ext.require(['widget.*', 'layout.*', 'Ext.data.*');  

用以下语法排除掉不需要的类:

[javascript]  view plain  copy
  1. Ext.exclude('Ext.data.*').require('*');  

用这种方式,依赖的类是异步加载的。如果在你定义的类中没有指定依赖的类,那么当使用 Ext.Create 创建实例时,如果它是未加载的,这时将会同步加载这些类文件。这对性能有一定的影响,所以当你定义类时,使用 Ext.require 指定所需的类总是更好的。

  • requires 属性加载需要的类时,当前类初始化之前被加载。
  • uses 属性加载需要的类时,当前类初始化之后被加载。
  • singleton:true 属性当前类初始化时,该实例是一个单例对象。

注意:定位类的文件路径是基于类名的。例如:MyApp.view.About 类的路径应该是 \myapp\view\ about.js 。


Events(事件)

一个事件可以是一个用户操作,一个 Ajax 调用的响应等等。

Adding listeners(添加事件监听)

当你创建对象或者创建以后都可以为这个对象添加监听器。下列示例代码为这个对象添加了一个 单击事件 的监听:

[javascript]  view plain  copy
  1. Ext.create('Ext.Button', {     
  2.     renderTo: Ext.getBody(),     
  3.     listeners: {       
  4.         click: function() {  
  5.             Ext.Msg.alert('Button clicked!');  
  6.         }  
  7.     }  
  8. }) ;  

 

你可以添加多个事件监听,如以下代码示例:

[javascript]  view plain  copy
  1. Ext.create('Ext.Button', {     
  2.     renderTo: Ext.getBody(),     
  3.     listeners: {       
  4.         mouseout: function() {  
  5.             //Do something  
  6.         },       
  7.         click: function() {         
  8.             // Do something  
  9.         }     
  10.     }   
  11. });  


你也可以在对象创建之后,使用 on 方法为对象添加事件监听:

[javascript]  view plain  copy
  1. var button = Ext.create('Ext.Button');  
  2. button.on('click', function() {  
  3.    //Do something  
  4. }) ;  


同样的,你也可以使用 on 方法一次添加多个事件的监听,如以下代码示例:

[javascript]  view plain  copy
  1. var button = Ext.create('Ext.Button');  
  2. button.on({  
  3.     mouseover: function() {  
  4.         //Do something  
  5.     },  
  6.     mouseover: function() {  
  7.         //Do something  
  8.     }  
  9. }) ;  


Removing listeners (删除事件监听)

你也可以移除事件监听器, 但是你必须有 事件处理函数的引用; 你不能用匿名函数

[javascript]  view plain  copy
  1. var HandleClick= function() {  
  2.     Ext.Msg.alert('My button clicked!');  
  3. }  
  4.    
  5. Ext.create('Ext.Button', {     
  6.     listeners: {  
  7.        click: HandleClick  
  8.     }   
  9. }) ;   
  10.    
  11. button.un('click', HandleClick);  


页面 DOM 元素的事件处理

你可以将监听器添加到 DOM 元素,如下所示。

假设在你的 HTML 代码中,有一个 div 元素 id=mydiv ,如以下代码所示:

[html]  view plain  copy
  1. <div id="mydiv"></div>  

用下列代码为它添加事件监听:

[javascript]  view plain  copy
  1. var div = Ext.get('mydiv');  
  2. div.on('click', function(e, t, eOpts) {  
  3.     // Do something   
  4. });  
 


访问 DOM

有三种方法来访问 DOM 元素:get,query,和 select 。

Ext.get

get 方法是根据这个 DOM 元素的 ID 检索获取并封装为 Ext.dom.Element 对象:

[javascript]  view plain  copy
  1. var mydiv = Ext.get('myDivId');  

Ext.query

这种方式基于传入的 CSS 选择器 从给定的根节点开始查找。它返回一个匹配选择器的元素(HTMLElement[]/Ext.dom.Element[])数组。如果没有匹配的,返回一个空值的数组对象。

在下面示例中,myCustomComponent.getEl().dom 是传递的根节点。Ext.query 将检索这个节点内的子元素,并返回一个数组包含 CSS class 为 ‘oddRow‘ 的的元素:

[javascript]  view plain  copy
  1. var someNodes = Ext.query('.oddRow', myCustomComponent.getEl().dom);  


Ext.select

给出一些 CSS/XPath 选择器,Ext.select 方法返回一个 CompositeElement 类型的对象,代表一个元素的集合。

这个 CompositeElement 对象可以进行过滤,迭代,和对整个集合执行整体操作等等:

[javascript]  view plain  copy
  1. var rows = Ext.select('div.row'); ////Matches all divs with class  
  2. row rows.setWidth(100); // 这是设置所有元素的宽度为 100  

你也可以用一行代码,如下所示:

[javascript]  view plain  copy
  1. Ext.select('div.row').setWidth(100);  


多重选择器

在方法调用时通过指定多个搜索条件可以用来匹配多个元素:

[javascript]  view plain  copy
  1. Ext.select('div.row, span.title'); //匹配所有的 class 用 .row 的 div 元素,和匹配所有 class 用 .title 的 span 元素  

 

选择器 根

当你使用 select ,它默认取 HTML body 作为根并从默认的 body 开始检索整个 DOM 树。你可以通过制定一个根元素来避免这种情况,这样它将只搜索给定的根的子节点。

[javascript]  view plain  copy
  1. Ext.get('myEl').select('div.row');  

这儿使用了 ‘myEl’ 作为根节点。这将首先找到 id 为 ‘myEl’ 的元素,然后将在根元素(myEl)下面搜索出 class 为 ‘row’ 的 div 标签。

[javascript]  view plain  copy
  1. Ext.select('div.row', true, 'myEl');// This is equivalent to the previous line.  

 

链式选择器

下列的查询方式会匹配 class 为 row 并且 title 属性值为 bar 的 div ,这个 div 属于其父元素的首个子元素:

[javascript]  view plain  copy
  1. Ext.select('div.row[title=bar]:first')  

 

Ext.ComponentQuery

这允许你用 ID,xtype,和 属性查找一个组件。你可以全局搜索或者指定一个根组件。

下列查询将返回所有的 xtype 为 button 的组件:

[javascript]  view plain  copy
  1. Ext.ComponentQuery.query('button');  

得到一个 id 为 foo 的组件,用以下代码:

[javascript]  view plain  copy
  1. Ext.ComponentQuery.query('#foo');  

下列代码将返回所有的 xtype 为 button 并且 title 属性值为 my button 的组件:

[javascript]  view plain  copy
  1. Ext.ComponentQuery.query("button[title='my button']");; //or parent.query('textfield[title=my button]');  

你也可以使用嵌套选择器如下:You can also use nested selectors as follows:

[javascript]  view plain  copy
  1. Ext.ComponentQuery.query('formpanel numberfield'); // 这里获取 xtype 为 frompanel 下面的 xtype 为 numberfield 的组件  

下列代码返回这个 parent 容器内匹配传递进来的选择器的第一个直接子组件,如果没有匹配上,返回 null 。

[javascript]  view plain  copy
  1. parent.child('button[itemId=save]');  

同样的,你也可以使用其他的方法,例如 nextNode, up, down, previousSibling 等等。

 

 

组件,容器,和布局

Ext JS 提供了一组丰富的组件和布局,这使在 Ext JS 中开发 UI 变得超级简单,甚至非专业 UI 开发人员也能够轻易的使用。

组件

从简单的组件说起,例如 button 和 label ,到复杂的组件,例如 Tree Panel,Grids 等等,Ext JS 有大量的内置组件。所有的组件都派生自 Ext.Component 类,它提供支持创建,重绘,渲染和处理组件。

所有的组件都有一个属性叫做 xtype 。它是非常有用的,它用在当你不想马上实例化这个组件时,而是想让这个组件在实际被应用时才创建,就是我们俗称的懒加载。

 

容器

容器是一个特殊的组件类型,它能够持有其他组件。在 Ext JS 中 Ext.Container.Container 类是所有的容器的基础类。

Ext.toolbar.Toolbar, Ext.panel.Panel,  和 Ext.Editor 是一些内置组件。这些组件都是可以包含其他组件。而像 Ext.button.Button 类就不是派生自 Ext.container.Container ,所以它不能够包含其他组件。

一个典型的 Ext JS 应用包含一组嵌套的组件。看下面这个例子并思考:

[javascript]  view plain  copy
  1. Ext.create('Ext.panel.Panel', {     
  2.     renderTo:Ext.getBody(),     
  3.     width:700,  
  4.     height:400,  
  5.     items:[{       
  6.         xtype: 'panel',       
  7.         title: 'Panel 1',  
  8.     },{       
  9.         xtype: 'panel',       
  10.         title: 'Panel 2',       
  11.         height: 200,       
  12.         items: [{  
  13.             xtype: 'button',         
  14.             text: 'Click Me'  
  15.         }]  
  16.     },{       
  17.         xtype: 'panel',       
  18.         title: 'Panel 3',       
  19.         width: 150,       
  20.         height: 100  
  21.     }]  
  22. });  


在前面的代码中,这是嵌套的组件,结构如下图所示:

1

上面的代码运行后将输出类似以下截图:

1

布局

布局定义了包含的组件是如何定位的以及设定组件的尺寸大小。每一个容器都有一个布局。默认布局是 auto 。这将不会为子组件指定任何关于位置和大小的规则。

在上面的图中,你可能已经注意到这些子组件只是一个接一个嵌套在父级容器中。这是在代码中因为我们还没有为这些组件制定任何布局,默认情况下使用的是 auto 布局。

 

现在,让我们在相同的代码里使用一些布局。下列示例中,我们将使用 column 布局和 center 布局。

当你使用 column 布局,你可以指定 columnWidth 。所有的列的 columnWidth 的值的总和必须等于 1 。你也可以为一些列指定固定宽度,如以下代码所示。这里,Panel3 取了一个 150 的固定宽度,然后剩下的两列按照 columnWidth 的值分配剩下的宽度:

[javascript]  view plain  copy
  1. Ext.create('Ext.panel.Panel', {     
  2.     renderTo:Ext.getBody(),     
  3.     width:700,     
  4.     height:400,     
  5.     layout:'column',     
  6.     items: [{       
  7.         xtype: 'panel',       
  8.         title: 'Panel 1',       
  9.         columnWidth: 0.4,       
  10.         height: 400,  
  11.     },{       
  12.         xtype: 'panel',       
  13.         title: 'Panel 2',       
  14.         columnWidth: 0.6,       
  15.         layout: 'center',       
  16.         height: 400,       
  17.         items: [{  
  18.             xtype: 'button',         
  19.             text: 'Click Me'  
  20.         }]  
  21.     },{       
  22.         xtype: 'panel',       
  23.         title: 'Panel 3',       
  24.         width: 150,       
  25.         height: 400  
  26.     }]  
  27. });  

以上代码输出为:

1

updateLayout

updateLayout 是  Ext.container.Container 对象里的一个方法。这可以用来根据布局规则重新定位子组件。例如你修改了布局方式,需要动态的更新布局时。


suspendLayout

大多数时候你不会用到这个 updateLayout  方法,然而有些时候你必须调用它。

这个 updateLayout  方法是在你重绘和当你添加或删除了一个组件时自动调用。有时候你可能需要它暂停一下,不是马上就调用,特别是当你添加或删除多个子组件时。所以在这种情况下,你可以设置suspendLayout  属性为 true ,一旦你完成添加或删除组件的操作,你可以设置 suspendLayout 为 false 并在你的代码中手动调用 updateLayout 方法。

同样的如果你想对整个框架停止更新布局,你可以调用 Ext.suspendLayouts() ,然后在你的操作完成后你可以通过调用 Ext.resumeLayouts(true) 恢复它。

以下是 Ext JS 中可用的布局:

  • absolute
  • accordion
  • anchor
  • border
  • card
  • center
  • column
  • fit
  • hbox
  • table
  • vbox

absolute 绝对布局

这个布局使用 x 和 y 属性来指定组件的绝对定位:

[javascript]  view plain  copy
  1. Ext.create('Ext.panel.Panel', {     
  2.     renderTo:Ext.getBody(),     
  3.     width:700,     
  4.     height:400,     
  5.     layout:'absolute',     
  6.     items: [{       
  7.         xtype: 'panel',       
  8.         title: 'Panel 1',       
  9.         x: 12,       
  10.         y: 20,       
  11.         height: 250  
  12.     },{       
  13.         xtype: 'panel',       
  14.         title: 'Panel 2',       
  15.         x: 200,       
  16.         y: 150,       
  17.         height: 200  
  18.     },{       
  19.         xtype: 'panel',       
  20.         title: 'Panel 3',       
  21.         x: 400,       
  22.         y: 250,       
  23.         width: 150,       
  24.         height: 100  
  25.     }]  
  26. });  
 

这里所示的输出,你可以重叠组件因为他们用绝对位置定位的:

1

accordion 手风琴(可折叠)布局

这个布局展示了在一个时间里只有一个内置的可支持折叠和展开的子级 panel 。瞧一下以下示例:

[javascript]  view plain  copy
  1. Ext.create('Ext.panel.Panel', {     
  2.     renderTo: Ext.getBody(),     
  3.     width: 700,     
  4.     height: 400,     
  5.     layout: 'accordion',     
  6.     items: [{  
  7.         title: 'Item 1',  
  8.         html: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'  
  9.     },{  
  10.         title: 'Item 2',       
  11.         html: 'some content here'  
  12.     },{  
  13.         title: 'Item 3',       
  14.         html: 'empty'  
  15.     }]   
  16. });  

这里显示的输出,这个 Item 1 是展开的,而其他的 panel 是折叠的:

1

anchor 锚点布局

这个布局使你能够指定子级组件的大小,而这是相对于布局容器的。首先容器根据指定的锚点规则调整然后所有的子级组件再作调整:

[javascript]  view plain  copy
  1. Ext.create('Ext.panel.Panel', {     
  2.     renderTo: Ext.getBody(),     
  3.     width: 700,  
  4.     height: 400,     
  5.     layout: 'anchor',     
  6.     items: [{       
  7.         title: 'Item 1',       
  8.         html: 'Item 1',       
  9.         anchor: '50%'  
  10.     },{       
  11.         title: 'Item 2',       
  12.         html: 'Item 2',       
  13.         anchor: '-20 -200'  
  14.     },{       
  15.         title: 'Item 3',       
  16.         html: 'Item 3',       
  17.         anchor: '-200'  
  18.     }]  
  19. });  

输入如以下截图:

1

border 布局

这个布局允许你为子组件指定一个区域位置,例如 center,north,south,west 和 east。当你使用 border 布局时,在其内的组件必须有一个指定区域为 center,如下列代码所示:

[javascript]  view plain  copy
  1. Ext.create('Ext.panel.Panel', {     
  2.     renderTo: Ext.getBody(),     
  3.     width: 700,     
  4.     height: 400,     
  5.     layout: 'border',  
  6.     items: [{       
  7.         title: 'Item 1',       
  8.         html: 'Item 1',       
  9.         region: 'center'  
  10.     },{       
  11.         title: 'Item 2',       
  12.         html: 'Item 2',       
  13.         region: 'east',       
  14.         width: 200  
  15.     },{       
  16.         title: 'Item 3',       
  17.         html: 'Item 3',       
  18.         region: 'south',       
  19.         height: 100  
  20.     }]   
  21. }) ;  

以上代码输出类似下列视图:

1

 

card 卡片布局

在此布局中,只有一个子组件是可见的,这个组件基本上充满整个容器。卡片布局一般应用在向导或者 tabs:

[javascript]  view plain  copy
  1. Ext.create('Ext.panel.Panel', {     
  2.     renderTo: Ext.getBody(),     
  3.     width: 700,     
  4.     height: 400,     
  5.     layout: 'card',     
  6.     defaultListenerScope: true,     
  7.     bbar: ['->',{  
  8.         itemId: 'btn-prev',       
  9.         text: 'Previous',       
  10.         handler: 'showPrevious',       
  11.         disabled: true  
  12.     },{  
  13.         itemId: 'btn-next',       
  14.         text: 'Next',       
  15.         handler: 'showNext'  
  16.     }],     
  17.     items: [{       
  18.         index: 0,       
  19.         title: 'Item 1',       
  20.         html: 'Item 1'  
  21.     },{       
  22.         index: 1,       
  23.         title: 'Item 2',       
  24.         html: 'Item 2'  
  25.     },{       
  26.         index:2,       
  27.         title: 'Item 3',       
  28.         html: 'Item 3'  
  29.     }],  
  30.     showNext: function () {       
  31.         this.navigate(1);  
  32.     },  
  33.     showPrevious: function () {       
  34.         this.navigate(-1);  
  35.     },  
  36.     navigate: function (incr) {       
  37.         var layout = this.getLayout();       
  38.         var index = layout.activeItem.index + incr;       
  39.         layout.setActiveItem(index);  
  40.         this.down('#btn-prev').setDisabled(index===0);       
  41.         this.down('#btn-next').setDisabled(index===2);  
  42.     }  
  43. });  

卡片布局的输出。当你点击 next 按钮,将会显示 Item 2 面板:

1

center 中心布局

这种布局,容器的子组件在中间。在本章中开始介绍布局的部分,我们已经有一个例子了。


column 列布局

用此布局,你可以将容器划分为指定数量的列并指定每列所占的大小。这个例子也在本章开始介绍布局的部分中可以找到。


fit 适配布局

在此布局中,子组件将会自适应容器的尺寸。如下:

[javascript]  view plain  copy
  1. Ext.create('Ext.panel.Panel', {     
  2.     renderTo: Ext.getBody(),     
  3.     width: 700,  
  4.     height: 400,     
  5.     layout: 'fit',     
  6.     bodyPadding: 20,     
  7.     items: [{  
  8.         title: 'Item 1',  
  9.         html: 'Fills the container',  
  10.     }]  
  11. });  

下列截图展示以上代码的输出。注意:Item 1 组件与父级容器之间的空隙是我们指定了 bodyPadding 属性:

1

hbox 布局

这种布局与 column 布局几乎是一样的,但是这种布局允许你拉伸列的高度。这里使用 flex 选项为子组件设置水平的相对值:

[javascript]  view plain  copy
  1. Ext.create('Ext.panel.Panel', {     
  2.     renderTo: Ext.getBody(),     
  3.     width: 700,     
  4.     height: 400,     
  5.     layout:{       
  6.         type: 'hbox',       
  7.         pack: 'start',       
  8.         align: 'stretch',  
  9.     },  
  10.     items: [{  
  11.         title: 'Item 1',  
  12.         html: 'Item 1',      
  13.         flex: 1  
  14.     },{  
  15.         title: 'Item 2',       
  16.         html: 'Item 2',       
  17.         width: 100  
  18.     },{  
  19.         title: 'Item 3',       
  20.         html: 'Item 3',       
  21.         flex: 2  
  22.     }]   
  23. });  

上面代码输出:

1

table 表格布局

这个布局允许你渲染一个表格出来。你可以指定列数和行数,使用 rowspan 和 colspan 创建复杂布局:

[javascript]  view plain  copy
  1. Ext.create('Ext.panel.Panel', {     
  2.     renderTo: Ext.getBody(),     
  3.     width: 700,  
  4.     height: 400,     
  5.     layout:{       
  6.         type: 'table',       
  7.         columns: 3,       
  8.         tableAttrs: {         
  9.             style: {           
  10.                 width: '100%'  
  11.             }  
  12.         }  
  13.     },     
  14.     items: [{       
  15.         rowspan: 3,       
  16.         title: 'Item 1',       
  17.         html: 'Item 1'  
  18.     },{       
  19.         title: 'Item 2',       
  20.         html: 'Item 2'  
  21.     },{       
  22.         title: 'Item 3',       
  23.         rowspan: 2,       
  24.         html: 'Item 3'  
  25.     },{       
  26.         title: 'Item 4',       
  27.         html: 'Item 4'  
  28.     },{       
  29.         title: 'Item 5',       
  30.         html: 'Item 5'  
  31.     },{       
  32.         title: 'Item 6',       
  33.         html: 'Item 6'  
  34.     },{       
  35.         title: 'Item 7',       
  36.         html: 'Item 7'  
  37.     }]  
  38. });  

以下截图所示为前面 table 布局代码的输出结果:

1

VBox 布局

这个布局内,子组件是垂直向下一个接一个排列。看一下以下的示例代码:

[javascript]  view plain  copy
  1. Ext.create('Ext.panel.Panel', {     
  2.     renderTo: Ext.getBody(),     
  3.     width: 700,     
  4.     height: 400,     
  5.     layout:{       
  6.         type: 'vbox',       
  7.         pack: 'start',       
  8.         align: 'stretch',  
  9.     },     
  10.     items: [{  
  11.         title: 'Item 1',       
  12.         html: 'Item 1',       
  13.         flex: 1  
  14.     },{  
  15.         title: 'Item 2',       
  16.         html: 'Item 2',       
  17.         height: 100  
  18.     },{  
  19.         title: 'Item 3',       
  20.         html: 'Item 3',  
  21.         flex: 2  
  22.     }]  
  23. });  

这段代码所示的输出:

1

总结

在本章中,我们了解学习了在 Ext JS 中的基础类和这些类中常用的方法,你还学习了如何创建和扩展一个类。还有如何使用 事件 和 查询元素及组件的功能。


在下一章,我们将会看一看许多有用的组件,例如 buttons ,menus ,toolbars 等等。我们也将根据所学创建一个小型的计算器应用。

Cursor+WSL2+Puppeteer真实项目交付复盘 Node.js 是现代 Web 后端与自动化脚本的核心运行时,其事件循环机制和原生模块(native addon)兼容性直接决定工程落地效率;Puppeteer 作为基于 Chromium 的浏览器自动化工具,依赖底层系统环境稳定性,尤其在 Windows 与 Linux 混合开发场景中,WSL2 不仅提供类 Linux 构建环境,更通过内核级隔离规避 Windows Defender 干预、统一文件权限与路径行为,成为保障 Puppeteer 高可用的关键基础设施。本文聚焦真实商业项目交付过程,深入解析 阅读详情

相关推荐

Extjs6示例中文版

Ext Js 6 By Example 中文翻译 内容来自网上,保留网页上内容不做更改。

Ext4.2学习笔记-Ext.application

Ext.app.Application 代表一个ExtJS4 应用.这是一个典型的使用Viewport的单页应用.一个典型的Ext.app.Application 一般如下: Ext.application({ name:'MyApp', launch:function(){Ext.create('Ext.container.Viewport',{ ...

非原创 不发表--不一定精彩 但一定原创 313

ext js中文开发手册

ext js中文开发手册

关于Ext.application的执行顺序。

index.js如下: Ext.application({ name : 'cdkj', appFolder : base + '/static/js/com', paths : base + '/static/js/com',// 设置路径信息 controllers : [ 'login.UserLogin' ], launch : function() { alert(

看不过的黑工坊 3820

ensp VRRP+MSTP综合性实验

网络结构拓扑图 实验要求 要求: 1、全网互通,IP地址任意规划,路径最优,无环路。 2、AR1上面有一个loopback口,ip地址为1.1.1.1/24, 要求所有电脑能访问。 3、vlan10通过LSW1访问1.1.1.1,当LSW1出现问题即使 g0/0/1故障亦能通过lsw2访问。 vlan30通过LSW2访问1.1.1.1,当LSW2出现问题即使 g0/0/1故障亦能通过lsw1访问。 4、LSW1为vlan10的主根,vlan30的备根。 LSW2为vlan30的主根,vlan1

qq_45631844的博客 1万+

Xilinx XDMA IP核配置实战:AXI Memory Mapped vs Stream选型指南(附PCIe调试技巧)

本文深入解析Xilinx XDMA IP核配置中AXI Memory Mapped与AXI Stream两种DMA接口的核心区别与选型策略。针对PCIe高速数据传输场景,详细对比了二者在数据特性、延迟、硬件资源及软件复杂度上的差异,为FPGA工程师在数据采集、实时处理等项目中做出高效设计决策提供实战指南,并附有关键的PCIe调试技巧。

qsc901234的博客 585

Ext.app.Application简介

版本:6.2.1 简述: 代表性的ExtJS应用程序,通常是用Ext.container.Viewport创建的经典的单页面应用程序。 一个程序由一个或多个视图(View)组成。视图的行为表现由它对应的视图控制器(Ext.app.ViewController)和视图模型(Ext.app.ViewModel)管理。 全局的活动是由控制器(Ext.app.Controller)来调整的,这

清静致远 6461

Ubuntu登录界面黑屏?手把手教你排查和修复LightDM启动失败(附debug命令详解)

本文详细介绍了Ubuntu系统中LightDM(Light Display Manager)启动失败导致登录界面黑屏的排查与修复方法。通过系统状态检查、调试模式分析、常见故障解决方案及高级调试技巧,帮助用户快速定位并解决LightDM相关问题,恢复正常的图形登录环境。

weixin_34005090的博客 315

Ext JS 6学习文档–第2章–核心概念

核心概念 在下一章我们会构建一个示例项目,而在这之前,你需要学习一些在 Ext JS 中的核心概念,这有助于你更容易理解示例项目。这一章我们将学习以下知识点: 类系统,创建和扩展类 事件 Ext JS 对象的查询 容器 布局 class system(类系统) Ext JS 提供了很多功能,使得它创建和处理类变得简单。以下是在 Ext JS 6 的类系统中的几大组成类: ...

weixin_30593261的博客 370

波士顿咨询最新发布《2025年全球支付报告:未来不稳定》:到2029 年,支付收入将预计达到 2.4 万亿美元

波士顿咨询最新发布《2025年全球支付报告:未来不稳定》:到2029 年,支付收入将预计达到 2.4 万亿美元

face light~ 917

直流电机双闭环调速系统MATLAB仿真

Chopper-Fed DC Motor Drive This example shows a Chopper-Fed DC Motor Drive. Description The DC motor is fed by the DC source through a chopper which consists of GTO thyristor and free-wheeling diode ...

飞行动力的博客 2万+

ext入门学习

[align=center][color=darkred][/color] :arrow: ExtJs简介: ExtJS是一个用javascript写的,主要用于创建前端用户界面,使一个与后台技术无关的前端ajax框架。因此, 可以把ExtJs用在.Net Java 等各种开发语言开发的应用中。 获得ExtJS: ExtJs开源框架可以在官方网站上下载,网址:http//ext...

不安的天空 170

【GlobalMapper精品教程】072:GlobalmapperV25中文版下载地址及安装教程

GlobalmapperV25中文版下载地址及安装教程安装包位于专栏完整数据包中,请订阅后从优快云私信查收!最新GlobalMapper中文版入门实战实验教程,图文并茂,实用性强,内容包括:GM基础操作、数据处理及地形图制作、航测内业数据处理、点云处理、地形分析、空间分析、数据库建库入库等。配套完整案例数据,持续同步更新!订阅专栏后,从私信查收中文安装包永久版(中文23.0+24.0)及配套实验数据包。

智慧空间实验室 4733

自动化多语言JSON/YAML文件翻译:技术实现与最佳实践

在现代软件开发中,多语言支持已成为产品国际化的基本要求。然而,开发者面临着一系列技术挑战: 1. **重复性工作负担**:手动翻译JSON/YAML配置文件需要大量人力资源,特别是当项目包含数百个键值对时 2. **翻译一致性难题**:不同开发者对技术术语的理解差异导致翻译质量参差不齐 3. **模板变量保护**:动态内容如`{{username}}`和URL链接在翻译过程中容易被破坏 4. *

gitblog_00962的博客 232

把 SNC 支持的通信链路一次讲透,SAP GUI、RFC、CPIC、SAProuter 到底谁在保护谁

摘要: SNC(Secure Network Communications)是SAP系统中用于保护特定通信链路的安全机制,主要应用于DIAG、RFC、CPIC等SAP协议,而非HTTP等互联网协议(后者由SSL/TLS处理)。其核心在于保护通信端点之间的逻辑链路,需在发起方和接收方同时配置SNC参数,包括SNC名称、保护等级(QoP)等。实际项目中,SNC的配置涉及多个层面,如SAP GUI到ABAP平台的登录链路、外部程序通过RFC/CPIC连接ABAP的认证、ABAP系统间的跨系统通信等。配置不当可能导

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 250

EfficientNet 改进:StripCGLU模块的创新与应用

本文提出了一种改进的EfficientNet-b0模型,核心创新是通过引入StripCGLU模块来提升网络性能。StripCGLU结合了水平/垂直条带卷积和GLU激活机制,具有参数效率高、计算量少的优点。改进策略包括选择性替换部分MBConv为StripCGLU模块(每隔3个块插入),同时保留早期层结构。测试表明该模型适用于移动端视觉任务,在保持效率的同时提升性能。代码实现包含模块定义、模型构建及测试部分,展示了如何通过精心设计的模块改进现有网络架构。

Henry的博客 241

01-Docker入门与核心概念

要真正理解Docker,我们不能仅仅停留在"它是一个工具"的层面。任何一项技术的诞生都不是凭空而来的,它是对前人智慧的继承与发展,是对现实问题的回应。容器化技术同样如此——它有着超过四十年的技术积淀,经历了从chroot到LXC,再到Docker和Kubernetes的漫长演进。本章将带你穿越时光,梳理容器化技术的发展脉络,让你明白Docker为什么会出现在这个时代,以及它解决了前人没有解决好的哪些问题。软件交付方式的演进,本质上是人类对计算资源利用率和管理效率不断追求的过程。我们可以将这个过程分为三个主要

Na2SiO3Glue的博客 688

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

MuPDF JavaScript 绑定 Pixmap API 完全指南(SumatraPDF 仓库集成版)

Pixmap(像素图)是 MuPDF 渲染管线中最核心的光栅图像对象,承载了页面渲染、图像转换、颜色空间变换、条码识别与文档纠偏等一系列能力。本文以 SumatraPDF 仓库内 MuPDF 的 JavaScript 绑定参考文档为骨架,结合 [Pixmap.rst](https://link.gitcode.com/i/c592f03be6f4240c9d64ace1d0a848c9) 中定义的

gitblog_00529的博客 568

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

高级技巧:如何为 kernels 打包 Triton Autotune 配置,加速 AI 计算内核

kernels 是一个用于**构建计算内核并从 Hub 加载**的工具集,而 Triton 内核的性能很大程度上取决于 `BLOCK_SIZE_M`、`num_warps`、`num_stages` 等参数的选择。本指南将完整讲解 kernels 的 **Triton autotune 配置打包**技巧:提前为不同 GPU 和矩阵形状调好参、把结果以 JSON 文件随内核一起发布,从而让 GEMM

gitblog_00044的博客 1104

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Bun vs Node.js:JavaScript运行时性能重构与工程实践指南

JavaScript运行时是现代前端与全栈开发的底层基石,其启动速度、包管理效率和TypeScript支持能力直接决定开发体验与CI/CD效能。Node.js基于V8与libuv构建,虽生态成熟但存在启动延迟高、npm安装慢、TS编译链路冗长等系统性瓶颈;Bun则以Zig重写内核,融合运行时、包管理器、打包器与测试框架,实现毫秒级进程启动、SQLite加速依赖解析及AST直执行TS方案。它并非替代Node.js,而是针对构建、本地开发与类型化服务等高频场景提供可量化的性能跃迁——如bun install快1

weixin_34032792的博客 182

Intel One Mono 字体指南:从安装到开启编程连字,给写代码的人的等宽字体方案

Intel One Mono 是 Intel 开源的等宽字体家族,由 Frere-Jones Type 与 Intel 品牌团队合作设计,核心目标是提升长时间编码时的可读性。它提供 Light、Regular、Medium、Bold 四种字重及对应斜体,覆盖 200 多种使用拉丁文字的语言,共 1043 个字形。如果你每天在编辑器里盯八小时代码,希望 `0` 和 `O`、`1` 和 `l` 不再混

gitblog_00153的博客 664

MrRSS:如何通过自定义脚本与AI增强功能解决现代信息聚合的核心痛点

在信息爆炸的时代,传统RSS阅读器面临三大核心挑战:信息源碎片化、内容过载、语言障碍。MrRSS作为一款现代化的AI增强型RSS阅读器,通过创新的自定义脚本系统和智能AI功能,为这些痛点提供了系统性的解决方案。本文将深入探讨MrRSS如何通过技术架构的巧妙设计,让用户能够真正"定制"自己的信息流。 ## 信息源碎片化:自定义脚本打破技术壁垒 传统RSS阅读器的最大限制在于只能处理标准RSS/A

gitblog_00358的博客 335

从源码构建沙拉查词 Saladict 7:浏览器划词翻译扩展的完整工程化解析

> **导读**:本文以开源项目沙拉查词(Saladict)仓库根目录的 [README.md](https://link.gitcode.com/i/f2702429bf9bc55e18f4835e9158badd) 为骨架,系统讲解这款面向 Chrome / Firefox 的专业划词翻译与网页翻译扩展的核心能力、多端下载渠道,并重点深入"从源码构建"的完整流程——包括 `yarn pdf`

gitblog_00933的博客 170
上一篇: [Ext JS 6 By Example 翻译] 第1章 – 入门指南
下一篇: [Ext JS 6 By Example 翻译] 第3章 - 基础组件
Sukla
博客等级 码龄11年 56粉丝 242原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值