原文:Tailoring Your Ext JS 5 Application for a Multi-Device World
概述
鉴于当今设备和表单因素的扩散,要针对所有这些可能性来优化应用程序已经变得越来越复杂。虽然可以使用CSS响应这些环境条件,但典型的,如Ext JS应用程序这样,还是要包含大量的Javascript。在某些情况下,使用javascript来针对设备细节进行编码可能很简单,但也可能很快就会失控。好消息是,在Ext JS 5.1,提供了几个功能强大的工具来管理这种复杂性。
在先前的文章已经介绍了许多这样的技术。这有助于去了解与比较他们之间的异同,以便于选择适合的工具来完成手头的工作。
内联技术
要理解这些工具的最好方式就是通过一个简单的示例。下面假设需要针对不同的设置对面板定义不同的标题。对于某些设备的面板,在有足够的空间,因而更长的、描述性的标题更适合,而毒药小屏幕,则缩写的标题更适合。本练习的目的不在于讲解如何使用最好的方式来完成这个特定的目标,而是要确保所采取的技术不会被更复杂的示例的细节所掩盖。
platformConfig
属性platformConfig是在Ext JS 5.1中新添加的,可以在类定义中使用,或者可以基于当前平台或设备分类在创建类的实例时的配置对象中使用。在视图中使用时可能类似以下代码:
Ext.define('App.view.summary.Manufacturing', { extend: 'Ext.panel.Panel', title: 'Mfg Summary', platformConfig: { desktop: { title: 'Manufacturing Summary' } } });
以上代码和下面的直接方法具有相同的效果:
Ext.define('App.view.summary.Manufacturing', { extend: 'Ext.panel.Panel', title: testForDesktop ? 'Manufacturing Summary' : 'Mfg Summary' });
以上代码不是让你去比较platformConfig和三样运算符的优缺点,而是让你去了解platformConfig是如何被声明为了类的一部分的。因此,该方法的工作是与基类无关的。使用platformConfig而不使用内联逻辑的一个原因是这样可以保证视图作为一个纯数据可以被安全被定义为JOSN格式。
还可以使用platformConfig来配置实例:
Ext.define('App.view.summary.Manufacturing', { extend: 'Ext.panel.Panel', items: [{ xtype: 'panel', platformConfig: { desktop: { title: 'Manufacturing Summary' }, '!desktop': { title: 'Mfg Summary' } } }] });
也可以将上面代码直接转换为:
Ext.define('App.view.summary.Manufacturing', { extend: 'Ext.panel.Panel', items: [ Ext.merge({ xtype: 'panel' }, testForDesktop ? { title: 'Manufacturing Summary' } : { title: 'Mfg Summary' }) ] });
然而,在这里使用platformConfig,是合并在initConfig方法中进行处理的,也就是说,将platformConfig属性作为实例配置只有在类的构造函数中调用了initConfig方法时才能实现。而这也是Ext.Widget、Ext.Component、大部分数据包类(如store)和其他类使用Ext.mixin.Observable的原因。
在实例配置中通过修改对象的初始配置来使用platformConfig与在类声明中修改类主体来使用platformConfig类似。
responsiveConfig
Ext JS 5引入了responsiveConfig并通过混入或插件来启用它。responsiveConfig的不同之处在于它的规则和属性不只在创建实例时进行计算,还会在设备的方向或可视区域发生改变时进行计算。这相对于platformConfig来说会增加一些开销,通过监听窗口大小或方向的改变来处理可能来得更有效。
可以稍微调整一下要求,以便根据设备的大小来进行标题响应,而不是设备分类(“desktop”)。
Ext.define('App.view.summary.Manufacturing', { extend: 'Ext.panel.Panel', mixins: ['Ext.mixin.Responsive'], responsiveConfig: { 'width >= 600': { title: 'Manufacturing Summary' }, 'width < 600': { title: 'Mfg Summary' } } });
由于以上类使用了responsiveConfig,因而在这里使用了混入,这比使用插件的方式更有好处,因为这样可以避免为每要给实例创建一个插件。不过,在组件实例上使用的时候,就需要使用responsive 插件:
Ext.define('App.view.summary.Manufacturing', { extend: 'Ext.panel.Panel', items: [{ xtype: 'panel', plugins: 'responsive', responsiveConfig: { 'width >= 600': { title: 'Manufacturing Summary' }, 'width < 600': { title: 'Mfg Summary' } } }] });
以上代码要谨记的是宽度指的是可视区域的宽度,而不是组件宽度。
Ext.app.Profile
使用platformConfig和responsiveConfig,可以说是外科手术式的调整。而使用配置文件,则可以管理更大的差异。配置文件被添加到Ext JS 5.1中,且作为应用程序架构的一部分,它最初是在Sencha Touch中引入的。
通常,使用配置文件可在应用程序的顶层通过mainView(或Viewport)进行切换,这意味着可以通过当前的配置文件来控制应用程序创建完全不同的视图。
配置文件只可用于使用Ext.app.Application的应用程序,且必须如以下代码哪样列出不同的配置文件:
Ext.define('App.Application', { extend: 'Ext.app.Application', profiles: [ 'Desktop', 'Mobile' ] });
在每一个配置文件类内,isActive方法决定了该特定的配置文件应否为当前活动的配置文件:
Ext.define('App.profile.Desktop', { extend: 'Ext.app.Profile', mainView: 'App.view.desktop.Main', isActive: function () { return Ext.os.is.Desktop; }, launch: function () { console.log('Launch Desktop'); } });
可以在平板或桌面中尝试一下这个示例来看看配置文件的基本使用方式。也可以在这里查看示例的源代码。
配置文件不需要使用mainView配置项,并可以选择使用提供的launch方法来进行自定义处理。只有当前活动的配置文件的launch方法会被调用。
Sencha Cmd的生成配置
如果使用Sencha Cmd来创建应用程序,也可以使用它来创建配置文件,这功能是在Sencha Cmd 5.0中引入的。创建配置文件可以让你只需要单独一个HTML页面(应用程序)并在加载时选择多个生成版本。这类似于如何去选择一个 Ext.app.Profile实例,而实际上是加载不同的生成版本。这种选择的基础可能是环境、存储的Cookie,甚至可能是用户账号中存放在服务器的数据。
无论是如何进行检测的,只有被选择的生成的代码和CSS会被加载。这与Ext.app.Profile需要在生成中包含所有配置文件的代码不同。
Ext JS Kitchen Sink示例就是使用多生成配置文件来启用主题与区域切换的。它根据每一个生成配置创建了两个生成选择,并在URL中通过查询参数来选择所需的生成配置文件,这时候,在index.html中的代码类似如下代码:
var Ext = Ext || {}; Ext.beforeLoad = function(tags){ var theme = location.href.match(/theme=([w-]+)/), locale = location.href.match(/locale=([w-]+)/); theme = (theme && theme[1]) || (tags.desktop ? 'crisp' : 'crisp-touch'); locale = (locale && locale[1]) || 'en'; Ext.manifest = theme + "-" + locale; };
小结
有了许多工具在手,针对特定情况选择合适的工具是个问题。对于只是在加载时进行简单调整的情况,可以考虑platformConfig。对于更多动态条件的情况,建议responsiveConfig。如果是更大规模的情况,可以考虑Ext.app.Profile。
如果需要在平板电脑而不是桌面上(甚至于基于用户授权),让应用程序看起来完全不同,可以考虑Sencha Cmd生成配置,它可以从桌面生成中移除平板开销,反过来也一样。
由于没有放之四海而皆准的解决方案,Ext JS提供了不同的工具来增加灵活性和效率。他们一起工作有助于确保应用程序自然而然的适合广泛的各种设备。
作者:Don Griffin
Don Griffin is the Engineering Manger for Ext JS and Sencha Touch. He was an Ext JS user for 2 years before joining Sencha and has over 20 years of software engineering experience on a broad range of platforms. His experience includes designing web application front-ends and back-ends, native GUI applications, network protocols and device drivers. Don’s passion is to build world class products that people love to use.