原文地址:http://www.sencha.com/blog/integrating-ext-js-with-3rd-party-libraries/

作者:Kevin Kazmierczak
Kevin Kazmierczak is a Senior Technical Architect at Universal Mind, an innovative digital solutions agency that fuses the design capabilities of an interactive firm with the the technical expertise of a systems integrator. He specializes in building frontend applications using Objective-C, HTML/JS, and Flex. Kevin holds an MBA and a BA in Computer Science from Alfred University.

介绍

Ext JS提供了大量可高度自定义的直接就可以使用的内部组件。如果组件不在框架中,也可以容易的通过扩展类的方式,甚至通过浏览Sencha市场来获取所需要的组件。这工作可能需要花费大量的时间,有时候为了节省时间,会考虑使用没有包含在Ext JS组件系统的第三方库。针对这种情况,有许多解决方案,而最简单的方法就是创建一个自定义封装组件来处理库,这样就可以在应用程序中实现重用。

实现概述

封装组件的目的是通过将第三方库所需的逻辑封装起来以方便配置以及与Ext JS框架实现交互。对于在应用程序中使用多少第三方库的API,有很大的自由度。如果库相当简单,且希望对API的访问进行控制,那就可以将API的每一个方法都封装为对应的方法。这样就可以在想要引用额外的自定义逻辑的时候隐藏对不想公开的方法或拦截方法的调用。另一种方式是公开一些API中的根对象,以便其他控件可以自由的通过对象直接调用任何API方法。在大多数情况下,这可能是最终的解决办法,不过,不同的项目会有不同。

为了演示这一方式,将为Leaflet创建一个封装组件Leaflet是一个由Universal Mind的 Vladimir Agafonki创建的开源的Javascript地图库。在应用程序中将使用这个封装组件来显示一张地图,并提供一个按钮来将地图移动到一个指定位置。

Leaflet可以将来自许多不同的地图服务的地图块整合起来,这样就为地图的显示提供了极大的灵活性。在示例中,将使用CloudMade提供的地图块。可以到CloudMade的网站上注册一个免费账号,然后就可在后续的请求(后面的示例需要使用到)中使用获得的API密钥。要想了解更多的与地图块有关的信息,可访问Leaflet的网站。

添加库引用

在应用程序中,首先要做的是在HTML文件中添加库的引用,这样才可以使用库。在示例中,需要在HEAD元素内添加两行来引用Leaflet。在Leaflet快速入门指南的Leftlet安装文档中可获得更多的详细信息。

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.5/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.5/leaflet.js"></script>

创建自定义组件

接下来要做的是从Ext.Component扩展出Leaflet的封装组件。Ext.Component会使用一个空白的UI来搭建控件的骨架,不过,它提供了所有所需的框架方法以便让它在任何布局中都能运行得很好。

在集成第三方库的时候,通常都需要配置和初始化它来满足需求。对于示例,需要重写afterRender方法来处理Leftlet的初始化。这个方法会在自定义组件渲染到DOM并准备好与用户交互后运行。还需要添加类的别名和引用地图的配置变量。

Ext.define('Ext.ux.LeafletMapView', {
extend: 'Ext.Component',
alias: 'widget.leafletmapview',
config:{
map: null
},
afterRender: function(t, eOpts){
this.callParent(arguments); var leafletRef = window.L;
if (leafletRef == null){
this.update('No leaflet library loaded');
} else {
var map = L.map(this.getId());
map.setView([42.3583, -71.0603], 13);
this.setMap(map);
L.tileLayer('http://{s}.tile.cloudmade.com/{key}/{styleId}/256/{z}/{x}/{y}.png', {
key: 'YOUR_API_KEY',
styleId: 997,
maxZoom: 18
}).addTo(map);
}
}
});

下面逐句来研究一下afterRender的代码:

var leafletRef = window.L;
if (leafletRef == null){
this.update('No leaflet library loaded');
} else {
....
}

在这里尝试在window.L命名空间中访问Leaflet库。如果不能获取到库的引用,就使用一个信息来更新组件的html,提示加载库时出错。

var map = L.map(this.getId());

这里将传递Ext JS的组件id来创建Leftlet地图对象。默认情况下,由Ext.Component创建的HTML标记是DIV,而这正是Leaflet用来初始化地图组件所需的。在这里使用的是在渲染控件时Ext框架生成的id,而不是使用硬编码的id来引用DIV。这样的好处就是可以在应用程序中创建多个实例。

map.setView([42.3583, -71.0603], 13);

这句将地图的位置设置为马萨诸塞州的波士顿的纬度和经度,地图的缩放等级为13。有许多在线工具可以用来查找不同地点的纬度和经度。

this.setMap(map);

将地图引用设置给map变量,这样就可在后续代码中使用它来访问地图。

L.tileLayer('http://{s}.tile.cloudmade.com/{key}/{styleId}/256/{z}/{x}/{y}.png', {
key: 'YOUR_API_KEY',
styleId: 997,
maxZoom: 18
}).addTo(map);

这句代码将设置Leaflet使用CloudMade的地图块。假设你已经创建了一个账号并注册了你的应用程序,你就可以将得到一个API密钥放到YOUR_API_KEY中。不用去担心那个混乱的网址,当移动地图的时候,Leaflet会动态去加载地图块。如果需要了解更多的信息,建议查看Leaflet的API文档。

到目前为止,已经创建好基本的地图控件了,可以在应用程序中使用了。不过,实际上这还没有完全实现。如果就这样去使用它,会发现它并不是所期望的效果。地图的尺寸并没有填满布局。Leaflet需要随时调用名为invalidateSize()的方法来调整地图的尺寸,并让它渲染成这个尺寸。这个问题在封装组件中很容易解决。可以重写onResize方法来实现,这样,布局的尺寸变化就可以随时调用地图的invalidateSize方法。

添加以下代码到控件:

onResize: function(w, h, oW, oH){
this.callParent(arguments);
var map = this.getMap();
if (map){
map.invalidateSize();
}
}

这样,布局的改变且有一个有效的地图引用就可以随时进行调用。如果调整了尺寸,就会告诉Leaflet去执行invalidateSize方法。

现在,就可以在布局中使用组件了,而且会看到地图将在提供的布局尺寸内显示。如果布局因浏览器调整尺寸或滑块而改变,将会看到地图应用了新的尺寸。在自定义的封装组件中,通过了几行代码就可以让第三方库Leaflet在Ext JS布局系统运行得很好。

使用示例

下面创建一个简单的Ext JS应用程序来使用这个新的封装组件。

Ext.Loader.setConfig({
enabled: true,
paths:{
'Ext.ux':'ux'
}
}); Ext.require(['Ext.ux.LeafletMapView']); Ext.onReady(function() {
Ext.create('Ext.container.Viewport', {
layout: 'vbox',
items: [
{
xtype: 'leafletmapview',
flex: 1,
width: '100%'
}
]
})
});

这里创建了一个viewport来使用整个浏览器的尺寸并将地图渲染到整个视图。这样,将会看到一个波士顿地区的大地图以及一些简单的缩放控制。

接下来要做的是处理地图与外部控件的交互。下面将添加一个按钮,当单击它的时候,将地图缩放到一个位置。根据Leaflet文档,这需要调用map对象的setView方法,并纬度和经度的坐标数组以及缩放等级传递给它。所要做的,就是公开封装组件在afterRender方法中创建的map对象,然后在按钮中访问对象并调用它的方法。

在viewport的items数组中地图组件的上面添加以下代码:

{
xtype: 'button',
text: 'Show Buffalo',
listeners:{
click: function(){
var map = Ext.ComponentQuery.query("viewport leafletmapview")[0];
map.getMap().setView([42.8864, -78.8786], 13);
}
}
}

以上代码将显示一个按钮;当单击它的时候,代码将尝试去获得地图对象的引用,并更新视图到新的位置。在Ext JS应用程序中,有许多方式来引用组件,包括控制器的refs、Ext.ComponentQuery()等等。对于当前示例来说,最方便的是使用组件查询来找到在viewport中的地图组件。一旦获得引用,就可以调用getMap方法来获得Leaflet的地图实例并直接调用任何Leaflet的APi方法。

从这里开始,就可以根据自己的需要来实现组件。可以针对所有的安装参数添加配置属性,这样就可以使用Ext JS的配置参数代替第三方库的约定来自定义组件的每一个实例。还可以添加新属性来切换库功能。例如,可以添加一个属性来启用Leaflet的定位功能,这样就可通过浏览器的Geolocation API来找到你的位置。可以在我的GitHub库找到更完整的示例。

小结

所有的库都会有不同,且会出现更多的挑战,不过,这个概念将有助于在Ext JS或Sencha Touch应用程序中整合他们。在Sencha市场或GitHUB已经有许多封装组件,因此可能不需要创建你自己的封装组件。如果找不到所需要的库,那就要创建自己的封装组件,并将它分享到Sencha开发社区。

【翻译】在Ext JS集成第三方库的更多相关文章

  1. Android中集成第三方库的方法和问题

    Android中集成第三方库的方法和问题 声明: 1. 本文參考了网上同学们的现有成果,在此表示感谢,參考资料在文后有链接. 2. 本文的重点在第三部分,是在开发中遇到的问题及解决的方法.第一,第二部 ...

  2. 【翻译】Ext JS 6有什么新东西?

    工具包ToolKits 发布 包的命名 Fashion 图表 ItemEdit插件 网格 电子表格 可操作模式Actionable Mode和可访问性 LazyItems插件 屏幕阅读器支持可访问性 ...

  3. 整合 Ext JS 和第三方类库

    介绍 ExtJS提供了许多高度可定制化内置组件.如果它不在框架(framework)里面,你可以很容易的扩展这些类,或者浏览Sencha市场(Sencha Market) 寻找你可能需要的任何东西.那 ...

  4. Ext tabpanel集成第三方charts(echarts、amcharts等)的问题(报getstyle为null的错误)

    最近在做ext集成charts的功能,主要是使用tabpanel,将charts集成到tab中,随便切换tab选项就会报错崩溃. 之前演示的时候也发现了该问题,由于在tab项中有加载svg文件的操作, ...

  5. 【翻译】Ext JS 6.2 早期访问版本发布

    原文:Announcing Ext JS 6.2 Early Access 非常开心,Sencha Ext JS 6.2早期访问版本今天发布了.早期访问版本的主要目的是为了让大家进行测试并评估Ext ...

  6. Egret 集成第三方库 记录

    引入第三方库pureMVC 这次我们要使用到一个mvc开发框架-pureMVC,熟悉as3的朋友一定也对这个框架不陌生吧.不熟悉的也没关系,这个框架不是这次的主角.我们从 这里 下载pureMVC的T ...

  7. 【翻译】Ext JS最新技巧——2015-8-11

    原文:Top Support Tips Seth Lemmons:使用棒极了的Awesome Font Ext JS 6附带了一个新的海卫一主题,可以使用Font Awesome字体作为背景图像的图标 ...

  8. 【翻译】Ext JS 6 Beta发布

    原文:Ext JS 6 Beta is Now Available 概述 Ext JS 6的好处 新的Ext JS功能和工具 需要你的反馈意见 概述 很高兴,Ext JS 6 beta版本现在发布了. ...

  9. 【翻译】Ext JS 5的平板支持

    原文:Ext JS 5 Tablet Support Ext JS已被公认为桌面Web应用程序的领先框架.自从平板开始在全球挑战PC的销售,无论是个人还是企业,电脑横向的应用已经产生急剧的变化.Sen ...

随机推荐

  1. Docker简介/安装/使用

    什么是Docker?docker是一个开源的应用容器引擎,系统级的轻量虚拟化技术.应用程序的自动化部署解决方案,能够迅速创建一个容器,并在容器上部署和运行应用程序,并通过配置文件可以轻松实现应用程序的 ...

  2. Activtiy完全解析(二、layout的inflate过程)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/52457893 本文出自:[openXu的博客]   在上一篇文章<Activtiy完全 ...

  3. Scala:提取器(Extractor)

    http://blog.csdn.net/pipisorry/article/details/52902671 提取器是从传递给它的对象中提取出构造该对象的参数. Scala 标准库包含了一些预定义的 ...

  4. Android启动Activity

    Android和java启动的区别 不同于使用 main() 方法启动应用的其他编程范例,Android 系统会通过调用对应于其生命周期中特定阶段的特定回调方法在 Activity 实例中启动代码.有 ...

  5. Android Multimedia框架总结(十二)CodeC部分之OMXCodec与OMX事件回调流程

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52629449 前言:上篇文中分析 ...

  6. 剑指offer面试题6 重建二叉树(c)

  7. Python图片处理库之PIL

    这个模块对于Python2.7 的windows64位电脑而言,还真的是不好找啊.这里分享一个下载链接吧,需要的朋友可以下载下来.PIL For Windows64 Python2.7下面分享一下这个 ...

  8. 14 fragment 创建

    静态展示 注意 静态的开始进入界面的生命周期和动态的不同 详情:14 fragment注意点 步骤一:创建一个类继承 Fragment 代码类型一: package com.fmy.demo1; im ...

  9. Linux/Unix--设备类型

          在Linux以及所有的Unix系统中,设备被分为以下三种类型:       块设备       字符设备       网络设备        块设备通常写为 blkdev ,它是可以寻址的 ...

  10. 自定义android 4.0以上的对话框风格

    做个笔记,这里是Dialog的风格,如果是用AlertDialog创建的,不能直接用.在styles.xml的写法: <style name="DialogWindowTitle&qu ...