使用Sencha Touch构建iPad应用程序

这篇文章最初出现在问题213.net杂志 - 世界上最畅销的网页设计师和开发者杂志。

Sencha Touch是一个跨平台的库,面向下一代触控设备。这意味着我们可以利用这些年前端经验在iOS和Android设备上构建原生感觉的网络应用程序。另外,他们在基于WebKit的桌面上运行起来非常可爱
浏览器,Chrome和Safari。

你可以获得最新版本sencha.com/products/touch/download。文档,示例和社区都很棒,所以请将它们加入书签。 API文档位于docs.sencha.com/touch/1-1/

Sencha Touch is a cross-platform library aimed at next-gen, touchenabled devices

Sencha Touch是一个跨平台的图书馆,面向下一代,可触控的设备

是什么让它如此特别?好吧,Sencha背后的人(基于ExtJS)为我们完成了所有艰苦的工作,并创建了一套丰富且功能强大的工具来设计和控制你的应用程序。功能包括:

1.坚固的布局组件,包括标题,菜单栏,弹出框,面板和旋转木马
2.为移动设备制作的自定义活动,包括点击,双击,滑动和捏合
3.硬件加速转换
4.一个令人难以置信的数据驱动的模板系统

这意味着您可以轻松创建类似应用的布局,其中包含用户在移动设备上所期望的所有转换和交互,并且屏幕可以从您的数据源轻松更新。您将在本教程的课程中看到,基本上没有HTML,一小部分CSS和几百行JavaScript(包括评论),我们可以为您的iPad创建令人印象深刻的东西。 C'est很酷,不是吗?

我们将创建一个iPad应用程序,从Vimeo可爱的“Staff Picks”频道中提取最新(或随机)视频,并允许用户在旋转木马中浏览这些视频页面,然后点击以在popover中观看他们喜爱的视频。在后台我们将使用Sencha的数据存储和代理,因此更新非常简单。最后,我们将在本地存储数据,以便我们可以保存状态。让我们开始吧...

The ‘Just One More’ app pulls in the latest (or random) videos from Vimeo’s ‘Staff Picks’ channel

“Just One More”应用程序从Vimeo的“Staff Picks”频道中提取最新(或随机)视频

设置HTML

这不可能更简单。我们从一个空的开始标签,为Sencha Touch和OAuth添加JavaScript和CSS文件,最后是我们自己的JavaScript和CSS应用程序文件。让我们来看看:

还有一个

现在我们准备开始使用我们的主应用程序文件了。 Sencha Touch发射了一个OnReady一旦完成设置触摸事件等页面的事件。我们只是在其中添加我们的代码OnReady事件。

Ext.setup({tabletStartupScreen:'Default-Landscape.png',icon:'appIcon256.png',glossOnIcon:false,onReady:function(){//我们的代码将在这里...};});

因此,在为我们的应用程序设置了几个不言自明的变量之后,我们就可以开始构建代码了。

首先,我们将为我们的数据定义模型和存储,然后创建视图,最后启动一些Ajax来为所有数据提供支持。

模型,商店和代理

我们来定义一些术语。模型描述了我们为对象保留的信息(在我们的例子中是视频)。我们通过代理检索数据,代理将各个数据项转换为模型实例。然后将这些实例保存在商店中,该商店填充我们的视图。

首先,我们描述我们的模型,提供视频应具有的字段和方法:

//设置将保存在StoreExt.regModel中的模型('视频',{字段:['id','可用','描述','高度','thumbnail_medium','thumbnail_large','标题','url','username','width','watched'],markAsWatched:function(){var videoId = this.data.id; if(!isVideoWatched(videoId)){localStorage.watched + = videoId + ',';} this.set('watched','watched'); this.store.sync();}});

这些领域很简单;我们将直接从Vimeo API获取这些内容。我们添加了两个额外的字段:可得到我们可以告诉用户哪些视频有移动版本(iPad上也有),以及看着,跟踪他们观看的内容。商店和代理有点复杂。

//我们的JSON商店使用绑定到localstoragevar的代理视频存储= new Ext.data.JsonStore({storeId:'videos',proxy:{id:'video',model:'Video',type:'localstorage',reader :{type:'json',root:'video'}},监听器:{add:{fn:function(store,records,index){handleVideosAddedToStore(store,records,index);}},load:{fn: function(store,records,index){handleVideosLoadedFromLocalStorage(store,records,index);}},clear:{fn:function(store,records){handleVideosRemovedFromStore(store,records);}}}});

我们给商店一个id并定义它的代理,它充当我们的数据源和商店之间的桥梁:

1. 类型:localStorage:这意味着数据将与设备的HTML5本地存储同步
2. 型号:视频:这是我们之前定义的模型,代理将创建实例
3. 读者- 这指定了代理期望的数据类型以及JSON对象中的根。

然后,当数据被加载到商店时(从我们的Ajax调用),当数据被加载到商店时,我们会附加监听器(来自LocalStorage的通过我们的代理),以及当我们清理商店时。这些监听器函数中的每一个都只是调用UpdateCarousel,我们很快就会到达。

Sencha Touch is relatively straightforward to use, but it’s worth having a good look at the API documentation

Sencha Touch使用相对简单,但值得仔细研究API文档

模型,商店,代理和读者是最棘手的问题,因此值得阅读API文档中的不同选项。但这是定义的事物的模型方面。让我们继续布局组件。如果我们用简单的伪代码布局我们的应用程序,它将如下所示:

我喜欢从里到外工作,所以我们将创建四页(页数下面)我们的轮播并将它们保存在一个我们以后可以访问的数组中:

//为carouselvar pages = [];创建页面(var i = 0; i  '' 
'' ''

{} data.title

''
'' “]}));}

每个页面都有一个富有想象力的id第1页第2页等等,同样富有想象力的一类

有趣的部分是TPL部分,我们为每个视频缩略图创建一个HTML模板。所以,当我们用一组视频更新我们的页面时,每个div都会有视频的id,img src将获得视频的值Thumbnail_medium,h3将是标题,等等。

Test as you go, right in your browser – using Web Inspector, drop breakpoints into jom.js to see what calls are being made

在您的浏览器中进行测试 - 使用Web Inspector,将断点放入jom.js以查看正在进行的调用

接下来,我们创建轮播:

//创建carouselvar carousel = new Ext.Carousel({id:'carousel',items:pages,flex:1,listeners:{tap:{element:'el',fn:function(evt,target){showEmbeddedVideo( evt,target);},delegate:'。summary'}}});

项目旋转木马将是我们之前定义的页面,而柔性决定旋转木马应该占用多少屏幕1所有空间。

我们为'tap'事件添加了一个监听器,使用了相当漂亮的东西代表参数。这意味着只有当我用类命中DOM元素时才会触发tap事件摘要- 随后将作为'目标'参数传递给我们ShowEmbeddedVideo处理程序。

//创建headervar header = new Ext.Panel({dock:'top',id:'header',height:185,html:' 

还有一个

“});

标题的唯一特征是码头属性。这指定标题将“停靠”到顶部,而不是与其余屏幕元素一起滚动。

//创建包装器(具有固定高度标题和滚动条)var wrapper = new Ext.Panel({fullscreen:true,layout:{type:'vbox',align:'stretch'},items:[carousel], dockedItems:[header]});

最后,我们创建了包装面板来保存所有内容。值得注意的是布局属性,它指示其中的元素一个在另一个之上(VBOX并且它被拉伸以填满整个屏幕。

Items和dockedItems是我们在上面创建的组件。所以我们已经定义了模型并设置了布局元素:现在我们只需要添加一些功能。

把它们捆绑在一起

应用程序的功能部分再次使用伪代码,如下所示:

在启动时:

1.将视频从本地存储加载到商店
2.更新轮播

当用户点击菜单项时:

3.拨打Ajax电话以获取更多视频
4.将这些添加到商店并同步回本地存储
5.更新轮播

当用户点击缩略图时:

6.在弹出窗口中显示视频
7.将视频标记为在商店和本地存储中观看

当应用程序启动时,我们会调用在里面功能:

/ * INIT * / var init = function(){//获取状态('latest'或'random')state = getState(); if(!calling){calling = state; } //将菜单设置为当前状态并添加tap handlersetSelectedMenuItem(state); Ext.select('li',false,'menu')。on({tap:handleMenuTap}); //从本地storagevideoStore加载商店.load(); //确保我们有最新的视频(state =='latest'){getNewVideos();}}();

在检查用户是否最后查看最新或随机视频(并相应更新菜单)后,我们从中加载视频LocalStorage的进入商店。这就像打电话一样简单VideoStore.load()

然后商店开火了加载事件,我们为我们设置的事件监听器提供服务音像店早。这个事件监听器基本上叫做UpdateCarousel

var updateCarousel = function(data){//将轮播移回startcarousel.setActiveItem(0,'slide'); //隐藏加载messageloading.hide(); //将数据分成pagesfor(var i = 0; i 

UpdateCarousel接收一系列视频。对于我们旋转木马中的每个页面,我们将抓取这些视频的页面大小(PageData将是一个包含12个视频的数组)并通过调用将它们加载到页面中Page.update(pageData)

新视频

回到我们定义轮播的页面时,我们定义了一个模板(TPL我们打电话时使用的属性)Page.update- 对于每个视频PageData数组,使用视频的id创建div,使用标题创建h3,依此类推。

因此,当用户点击时最新要么随机的我们称之为菜单GetNewVideos

var getNewVideos = function(){var page = 1; if(calling =='random'){//在Vimeo的40页Staff Spspage = Math.floor(Math.random()* 39中将页面设置为随机页面)+ 2;} var apiUrl ='http://vimeo.com/api/rest/v2';var parameters = {method:'vimeo.channels.getVideos',channel_id:'staffpicks',per_page:numberOfVideosToDownload,page: page,full_response:'true',格式:'jsonp',回调:'Ext.util.JSONP.callback'}; Ext.util.JSONP.request({url:getUrlWithSignature(apiUrl,parameters),callback:function(response) ){handleNewVideos(response);}});};

这非常简单。在决定从Vimeo请求哪个Staff Picks请求之后,我们使用Sencha的内置函数进行JSONP调用。在回调中我们检查状态是否正常,然后调用HandleNewVideos

var handleNewVideos = function(response){if(response.stat =='ok'){videos = response.videos.video; //删除当前videosvideoStore.removeAll(); //循环播放视频,创建新的模型instancesvar instances = []; for(var i = 0,j = videos.length; i  1)? 'mobile':'online',thumbnail_medium:video.thumbnails.thumbnail [1] ._ content,thumbnail_large:video.thumbnails.thumbnail [2] ._ content,title:video.title,username:video.owner.realname, width:video.width,watched:isVideoWatched(video.id)? 'watched':''},'Video',video.id); instances.push(instance);} //将新项插入storevideoStore.add(instances); //保存statesaveState();} else {alert ('抱歉,我们无法联系Vimeo获取更多视频。请稍后再试......'); setSelectedMenuItem(state); loading.hide();}};

当我们从Vimeo收到视频时,我们做了三件事:

1.从商店中删除现有视频:VideoStore.removeAll()
2.循环播放视频并创建视频模型实例,为商店做好准备
3.将新视频添加到商店:VideoStore.add(实例)

请记住,当我们加载视频时LocalStorage的进入商店,它解雇了加载它所称的事件UpdateCarousel?当我们将视频添加到商店时,会发生同样的情况。

触发事件,同步商店(将我们的新视频复制到LocalStorage的)和电话UpdateCarousel

我们完成了!

而且,我的朋友们,完成了循环。在启动时,该应用程序从中加载视频LocalStorage的并将它们显示在旋转木马的页面中,您可以轻扫。

点击菜单会对新视频进行Ajax调用,将这些视频添加到商店,然后同步回来LocalStorage的然后再次在转盘中显示它们。

We don’t touch on watching videos in this tutorial, but it’s all in the source code

在本教程中,我们不会涉及观看视频,但这些都在源代码中

我们没有涉及观看视频,但这是源代码,您可以在上面下载。玩一下代码,看看你能创造什么。祝你好运!

您可以通过从App Store下载(搜索“仅一个”)来玩最终应用程序的所有iPad荣耀。我们希望您能在欣赏最精美的Vimeo短片的同时享受乐趣。继续,再来一个......



翻译字数超限