许多类在使用配置对象创建(实例化)类时具有使用的快捷名称。快捷名称称为别名
(如果类扩展了 Ext.Component,则称为xtype
)。对于适用的类,别名/xtype 会列在类名称旁边以供快速参考。
框架类或其成员可以指定为私有
或受保护
。否则,类/成员为公有
。公有
、受保护
和私有
是访问描述符,用于传达如何以及何时使用类或类成员。
公有类和类成员可供任何其他类或应用程序代码使用,并且可以依赖它们在主要产品版本中稳定且持久。公有类和成员可以通过子类安全地进行扩展。
受保护类成员是稳定的公有
成员,旨在由所有者类或其子类使用。受保护成员可以通过子类安全地进行扩展。
私有类和类成员由框架内部使用,不打算由应用程序开发人员使用。私有类和成员可能会随时在不通知的情况下更改或从框架中省略,并且不应在应用程序逻辑中依赖它们。
静态
标签。*请参阅下面的静态。下面是一个示例类成员,我们可以对其进行剖析以显示类成员的语法(在本例中,从 Ext.button.Button 类查看的 lookupComponent 方法)。
我们来看看成员行中的每一部分
lookupComponent
)( item )
)Ext.Component
)。对于不返回 undefined
以外任何内容的方法,可以省略此内容,或者可以显示由正斜杠 /
分隔的多个可能值,表示返回的内容可能取决于方法调用的结果(即,如果 get 方法调用成功,则方法可能返回一个组件,如果失败则返回 false
,将显示为 Ext.Component/Boolean
)。PROTECTED
- 请参见下面的标志部分)Ext.container.Container
)。如果成员源自当前类,则源类将显示为蓝色链接;如果成员是从祖先或混合类继承的,则显示为灰色。查看源
)item : Object
)列出。undefined
,则“返回”部分将记录返回的类或对象类型以及描述(在此示例中为 Ext.Component
)自 3.4.0 起可用
- 示例中未显示),就在成员描述之后默认为:false
)API 文档使用许多标志来进一步传达类成员的功能和意图。标签可以用文本标签、缩写或图标表示。
classInstance.method1().method2().etc();
false
,则标记为可预防的事件不会触发- 表示框架类
- 单例框架类。*有关更多信息,请参见单例标志
- 组件类型框架类(Ext JS 框架中任何扩展 Ext.Component 的类)
- 表示类、成员或指南在当前查看的版本中是新的
- 表示类型为 config
的类成员
- 表示类型为 property
的类成员
- 表示类型为 method
的类成员
- 表示类型为 event
的类成员
- 表示类型为 theme variable
的类成员
- 表示类型为 theme mixin
的类成员
- 表示类、成员或指南在当前查看的版本中是新的
在 API 文档页面的类名称下方是与当前类拥有的成员类型相对应的按钮行。每个按钮按类型显示成员数(此计数会在应用筛选器时更新)。单击按钮将导航到该成员部分。将鼠标悬停在成员类型按钮上将显示该类型的所有成员的弹出菜单,以便快速导航。
与类配置选项相关的 Getter 和 Setter 方法将显示在方法部分以及 API 文档和成员类型菜单的配置部分,位于它们所处理的配置的正下方。Getter 和 Setter 方法文档将位于配置行中,以便于参考。
您的页面历史记录保存在本地存储中,并显示在顶部标题栏正下方(使用可用空间)。默认情况下,仅显示与您当前查看的产品/版本匹配的搜索结果。您可以通过单击历史记录栏右侧的 按钮并选择“全部”单选按钮来展开显示内容。这将在历史记录栏中显示所有产品/版本的所有近期页面。
在历史记录配置菜单中,您还将看到最近访问的页面列表。结果按“当前产品/版本”和“全部”单选按钮进行筛选。单击 按钮将清除历史记录栏以及保存在本地存储中的历史记录。
如果在历史记录配置菜单中选择了“全部”,则会启用“在历史记录栏中显示产品详细信息”复选框选项。选中后,每个历史页面的产品/版本将与历史记录栏中的页面名称一起显示。将光标悬停在历史记录栏中的页面名称上也将以工具提示的形式显示产品/版本。
可以使用页面顶部的搜索字段搜索 API 文档和指南。
在 API 文档页面上,还有一个筛选器输入字段,它使用筛选器字符串筛选成员行。除了按字符串筛选外,您还可以按访问级别、继承和只读筛选类成员。这是使用页面顶部的复选框完成的。
API 类导航树底部的复选框筛选类列表以包括或排除私有类。
单击空搜索字段将显示您最近的 10 次搜索,以便快速导航。
每个 API 文档页面(除了 Javascript 基本类型页面之外)都有一个与该类相关的元数据菜单视图。此元数据视图将具有以下一项或多项
Ext.button.Button
类具有备用类名 Ext.Button
)。备用类名通常用于向后兼容。默认情况下,可运行示例(小提琴)会在页面上展开。你可以使用代码块左上角的箭头单独折叠和展开示例代码块。你还可以使用页面右上角的切换按钮切换所有示例的折叠状态。在页面加载之间会记住切换所有状态。
默认情况下,类成员会在页面上折叠。你可以使用成员行左侧的箭头图标或全局使用右上角的展开/折叠所有切换按钮来展开和折叠成员。
在较窄的屏幕或浏览器上查看文档将导致针对较小尺寸因素进行优化的视图。桌面和“移动”视图之间的主要区别是
可以通过单击 API 文档页面顶部的类名称来查看类源。可以通过单击成员行右侧的“查看源”链接来查看类成员的源。
当今的移动 Web 应用程序预期可在各种设备上运行,从最小的手机到最大的平板电脑。这些设备具有广泛的屏幕分辨率,并且以不同的方式使用。人们倾向于在外出时使用手机应用程序来快速收集一些信息或执行一些操作——通常在很短的时间内。平板电脑应用程序更有可能在较长时间内使用,通常在家里或其他可以长时间坐着的地方。
所有这些意味着人们期望在不同设备上获得不同的应用程序体验。但是,你的大部分应用程序逻辑和资产可以在不同的体验之间共享。为每个平台编写单独的应用程序既耗时、容易出错,而且很无聊。值得庆幸的是,设备配置文件为我们提供了一种简单的方法,可以在设备类型之间共享尽可能多的代码,同时可以轻松地为每种设备自定义行为、外观和工作流。
设备配置文件存在于 应用程序 的上下文中,例如,如果我们想使用手机和平板电脑配置文件创建电子邮件应用程序,我们可以定义在以下代码示例中显示的 app.js(如果不熟悉,请参阅 应用程序简介指南)
Ext.application({
name: 'Mail',
profiles: ['Phone', 'Tablet']
});
由于我们没有给应用程序一个 启动函数,所以目前它只加载这两个配置文件。按照惯例,它希望在 app/profile/Phone.js 和 app/profile/Tablet.js 中找到它们。以下代码显示了手机配置文件
Ext.define('Mail.profile.Phone', {
extend: 'Ext.app.Profile',
config: {
name: 'Phone',
views: ['Main']
},
isActive: function() {
return Ext.os.is('Phone');
}
});
平板电脑配置文件遵循相同的模式。在手机配置文件中,我们仅提供了三条信息 - 配置文件 名称、激活此配置文件时加载的可选附加 视图 集以及 isActive 函数。
isActive 函数确定给定的配置文件是否应在您的应用运行的设备上处于活动状态。到目前为止,最常见的方法是使用内置 Ext.os.is
方法(例如 Ext.os.is(Phone
) 为手机和平板电脑创建配置文件。您可以在 isActive
函数中编写任何您喜欢的代码,只要它始终为其运行的设备返回 true
或 false
即可。
加载配置文件后,将依次调用其 isActive 函数。第一个返回 true 的函数是应用程序启动时使用的配置文件。然后将此配置文件设置为应用程序的 currentProfile,并且应用程序准备加载其所有依赖项 - 构成该应用程序的模型、视图、控制器和其他类。它通过将其自己的依赖项与活动配置文件中指定的依赖项相结合来实现此目的。
例如,让我们修改我们之前的应用程序,以便它加载自己的模型和视图
Ext.application({
name: 'Mail',
profiles: ['Phone', 'Tablet'],
models: ['User'],
views: ['Navigation', 'Login']
});
最后,当我们在手机上加载应用程序时,手机配置文件被激活,应用程序加载以下文件
前三个项目在应用程序本身中指定 - 用户模型以及导航和登录视图。第四个项目由手机配置文件指定,并遵循特殊形式。根据惯例,特定于配置文件的类应定义在与配置文件同名的子目录中。例如,手机配置文件中指定的“Main”视图从 app/view/phone/Main.js 加载,而如果我们在应用程序中定义了“Main”,则它将从 app/view/Main.js 加载。
这适用于配置文件中加载的所有模型、视图、控制器和存储。这一点很重要,因为它使您能够轻松地在配置文件之间共享行为、视图逻辑等(请参阅下面的专门视图和控制器部分)。如果您需要加载不符合此惯例的类,则可以改而指定完整的类名
Ext.define('Mail.profile.Phone', {
extend: 'Ext.app.Profile',
config: {
name: 'Phone',
views: ['Main', 'Mail.view.SpecialView'],
models: ['Mail.model.Message']
},
isActive: function() {
return Ext.os.is('Phone');
}
});
从这个例子可以明显看出,您可以混合匹配完全限定的类名(例如 'Mail.view.SomeView')和相对指定的类名(例如 'Main',它变为 'Mail.view.phone.Main')。请注意,为配置文件指定的模型、视图、控制器和存储都将以这种方式处理。这意味着如果您有仅想要为平板电脑加载的模型或存储,但不想创建像 Mail.model.tablet.User 这样的类,则应该改而指定完全限定的类名(在这种情况下为 Mail.model.User)。
使用配置文件的启动过程与不使用配置文件的启动过程几乎完全相同。基于配置文件的应用程序具有 3 阶段启动过程;在加载所有依赖项后,将发生以下情况
在使用配置文件时,通常使用配置文件启动函数来创建应用程序的初始 UI。在许多情况下,这意味着应用程序的启动函数被完全删除,因为初始 UI 在每个配置文件中通常不同(您仍然可以指定一个应用程序范围的启动函数,用于设置分析或其他与配置文件无关的设置等项目)。
典型的配置文件启动函数可能如下面的示例所示
Ext.define('Mail.profile.Phone', {
extend: 'Ext.app.Profile',
config: {
name: 'Phone',
views: ['Main']
},
isActive: function() {
return Ext.os.is('Phone');
},
launch: function() {
Ext.create('Mail.view.phone.Main');
}
});
请注意,配置文件和应用程序启动函数都是可选的 - 如果您没有定义它们,则不会调用它们。
配置文件实现的大部分专门化发生在视图和控制器中。让我们假设我们有以下平板电脑配置文件
Ext.define('Mail.profile.Tablet', {
extend: 'Ext.app.Profile',
config: {
views: ['Main']
},
launch: function() {
Ext.create('Mail.view.tablet.Main');
}
});
当此应用程序在平板电脑设备上启动时,文件 app/views/tablet/Main.js 会像往常一样加载。以下代码示例是 app/views/tablet/Main.js 文件的内容
Ext.define('Mail.view.tablet.Main', {
extend: 'Mail.view.Main',
config: {
title: 'Tablet-specific version'
}
});
通常,当我们定义视图类时,我们扩展 Sencha Touch 内置的视图之一,但在上一个示例中,我们扩展了 Mail.view.Main,这是我们自己的视图之一。以下代码示例说明了 Mail.view.Main 的样子
Ext.define('Mail.view.Main', {
extend: 'Ext.Panel',
config: {
title: 'Generic version',
html: 'This is the main screen'
}
});
因此,我们有一个超类 (Mail.view.Main) 和一个特定于配置的子类 (Mail.view.tablet.Main),它可以自定义超类的任何方面。在这种情况下,我们在子类中将 Main 视图的标题从“通用版本”更改为“特定于平板电脑的版本”,以便在应用程序加载时看到它。
由于这些是普通类,因此使用灵活的配置系统可以轻松自定义超类的几乎任何部分。例如,假设我们也有该应用程序的手机版本,我们可以按照以下方式自定义其 Main 视图的版本 (app/view/phone/Main.js)
Ext.define('Mail.view.phone.Main', {
extend: 'Mail.view.Main',
config: {
title: 'Phone-specific version',
items: [
{
xtype: 'button',
text: 'This is a phone...'
}
]
}
});
虽然上一个示例很有用,但更常见的是共享视图的某些部分,并以不同的方式将它们拼接在一起以适应不同的配置。例如,想象一个电子邮件应用程序,其中平板电脑 UI 是一个分屏,左侧是邮件列表,右侧加载当前邮件。手机版本是完全相同的邮件列表和类似的邮件视图,但这次是在卡片布局中,因为没有足够的屏幕空间同时显示这两个视图。
为了实现这一点,我们必须创建两个共享的子视图 - 邮件列表和邮件查看器。在每种情况下,我们都简要地省略了类配置
Ext.define('Mail.view.MessageList', {
extend: 'Ext.List',
xtype: 'messagelist'
// config goes here...
});
和邮件查看器
Ext.define('Mail.view.MessageViewer', {
extend: 'Ext.Panel',
xtype: 'messageviewer'
// config goes here...
});
最终,为了实现包含两个视图的目标布局,平板电脑 Main 视图可以使用以下代码
Ext.define('Mail.view.tablet.Main', {
extend: 'Ext.Container',
config: {
layout: 'fit',
items: [
{
xtype: 'messagelist',
width: 200,
docked: 'left'
},
{
xtype: 'messageviewer'
}
]
}
});
这在左侧创建了一个 200px 宽的邮件列表,并使用设备屏幕空间的其余部分来显示邮件查看器。现在让我们假设我们想要实现手机布局
Ext.define('Mail.view.phone.Main', {
extend: 'Ext.Container',
config: {
layout: 'card',
items: [
{
xtype: 'messagelist'
},
{
xtype: 'messageviewer'
}
]
}
});
在这种情况下,我们使用带有卡片布局的容器(一次只显示一个项目的布局),并将列表和查看器都放入其中。在这种情况下,我们仍然需要添加一些逻辑,告诉容器在列表中的邮件被点击时显示邮件查看器,但我们已经轻松地在基于当前加载的配置的不同配置中重用了我们的两个子视图。
与上一个示例类似,我们可以为每个配置自定义两个共享视图 - 例如,我们可以创建 Mail.view.phone.MessageViewer 和 Mail.view.tablet.MessageViewer 子类,它们都扩展了 Mail.view.MessageViewer 超类。这使我们能够再次在这些类之间共享大量视图代码,同时针对实际使用的设备提供适当的自定义。
与视图类似,许多应用程序都有一些可以在多个配置中共享的控制器逻辑。对于配置,最重要的差异通常与工作流相关。例如,应用程序的平板电脑配置可能允许你在一个页面上完成工作流,而手机配置则提供多页向导。
在以下示例中,我们有一个简单的手机配置,它加载一个名为 Main 的视图和一个名为 Messages 的控制器。与之前一样,此应用程序加载 app/view/phone/Main.js 和 app/controller/phone/Messages.js
Ext.define('Mail.profile.Phone', {
extend: 'Ext.app.Profile',
config: {
views: ['Main'],
controllers: ['Messages']
},
launch: function() {
Ext.create('Mail.view.phone.Main');
}
});
由于我们已经知道我们的手机和特定于平板电脑的控制器共享它们的大部分功能,因此我们在 app/controller/Messages.js 中创建了一个控制器超类
Ext.define('Mail.controller.Messages', {
extend: 'Ext.app.Controller',
config: {
refs: {
viewer: 'messageviewer',
messageList: 'messagelist'
},
control: {
messageList: {
itemtap: 'loadMessage'
}
}
},
loadMessage: function(item) {
this.getViewer().load(item);
}
});
上一个示例中的控制器执行三个操作
itemtap
事件,并在触发 itemtap
时调用 loadMessage()
函数。loadMessage()
时将选定的邮件项加载到查看器中。现在,我们可以按如下方式创建特定于手机的控制器
Ext.define('Mail.controller.phone.Messages', {
extend: 'Mail.controller.Messages',
config: {
refs: {
main: '#mainPanel'
}
},
loadMessage: function(item) {
this.callParent(arguments);
this.getMain().setActiveItem(1);
}
});
此代码扩展了 Messages 超类控制器并提供了以下功能
loadMessage
函数以执行原始逻辑,然后将主面板的活动项设置为消息查看器。整个超类配置由扩展它的子类继承。对于重复的配置(例如 refs),将合并配置,因此手机消息控制器类有三个 ref - main、viewer 和 messageList。与扩展其他类的任何类一样,我们可以使用 callParent
扩展超类中的现有函数。
请记住,Mail.controller.Messages 超类未被应用程序或配置文件声明为依赖项。它会自动加载,因为我们的 Mail.controller.phone.Messages 控制器对其进行了扩展。
在前面的示例中,我们能够共享我们的一些(但不是全部)refs。我们还能够通过使用控制器的 control 配置共享我们监听的单个事件。一般而言,应用程序在不同配置文件之间的差异越大,可共享的 ref 和控制配置就越少。
应在配置文件之间共享的一个控制器配置是 routes。此配置将 URL 映射到控制器操作,并提供后退按钮支持和深度链接。将 routes 配置保留在超类中非常重要,因为无论设备如何,相同的 URL 都应映射到相同的内容。
例如,如果朋友正在使用应用程序的手机版本,并向你发送了她当前所在应用程序页面的链接,你应该能够在平板电脑设备上点击该链接,并看到该 URL 的平板电脑特定视图。将所有路由保留在超类中,使你能够保留一致的 URL 结构,无论设备如何。
模型的自定义频率低于控制器和视图,因此通常不需要子类。在这种情况下,我们只为模型指定完全限定的类名
Ext.define('Mail.profile.Tablet', {
extend: 'Ext.app.Profile',
config: {
models: ['Mail.model.Group']
}
});