首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

Dojo mobile TweetView 系列课程之四 —— 创建Setting视图

2013-10-24 
Dojo mobile TweetView 系列教程之四 —— 创建Setting视图分类:?Javascript?Dojo扩展 (dojox)?综合?Dojo Mo

Dojo mobile TweetView 系列教程之四 —— 创建Setting视图

分类:?Javascript?Dojo扩展 (dojox)?综合?Dojo Mobile2011-06-10 10:25?1888人阅读?评论(0)?收藏?举报dojomobiletwitterfunctionjavascriptclass?

目录(?)[+]

?

作者:David Walsh

翻译:Siqi (siqi.zhong@gmail.com)

原文:TweetView: Creating the Settings View

?

在上一篇教程Dojo mobile TweetView 系列教程之三——Tweets和Mentions视图?中,我们夯实了TweetView应用程序的文件结构,回顾了创建TweetView的目标并通过编写tweetview._ViewMixin和tweetview.TweetView创建了Tweets和Mentions视图。本教程将重点介绍TweetView中的"Setting"视图:类的依赖关系、Setting视图是如何和Tweet、Mention视图联系在一起的、并编写Setting视图的代码。

?

?

版本:1.6

难度:中级

系列:TweetView

“Settings”视图的依赖关系

Settings视图是三个视图中最简单的。该视图包含两个标题(主标题和副标题),和一个Twitter账户列表,每一个Twitter账户都对应着一个开关用以控制该账户的信息是否需要在其他两个视图中显示。在看过下面的效果图之后,可以知道将会用到以下控件:

Dojo mobile TweetView 系列课程之四 —— 创建Setting视图

dojox.mobile.ScrollableView - 整个视图dojox.mobile.Heading - 主标题"Setting"dojox.mobile.RoundRectCategory - 副标题"Show"dojox.mobile.RoundRectList - 账户列表容器dojox.mobile.ListItem - 账户列表元素dojox.mobile.Switch - 开关空间

该效果图还清楚的说明了我们将会需要从Twitter获取用户的头像信息,因此我们还需要一些其他的Dojo资源:

dojo.io.script - 使用JSONP从Twitter获取信息dojo.DeferredList - 让我们可以一次处理多个Twitter信息请求所返回的数据

这些资源将帮助我们顺利完成Settings视图。与我们创建Tweets和Mentions视图的做法类似,我们将为Settings视图创建一个自定义类:SettingsView。

?

!如果我们不在Settings视图显示用户的头像信息,我们就不需要dojo.io.script和dojo.DeferredList。我们可以写死这些头像图片的路径,但是这样的话我们需要在每次用户更改他们头像时手动更新这些图片的路径。幸运的是我们之前创建的TweetView视图的代码已经包含了这些资源,所以在Settings视图中使用它们不会导致代码膨胀——这些资源提供的类已经可以用啦!

?

开发Setting视图

我们的SettingsView类和TweetView类非常相似,他们都继承dojox.mobile.ScrollableView和tweetview.ViewMixin。很重要的一点是SettingView类只是一个包装了整个应用程序用以获取账户信息的tweetview.ACCOUNTS对象的容器。在明白了这一点之后让我们看一下Settings视图的具体实现吧。

?

新的类:Settings视图

我们新的类叫做SettingsView,它的基础结构和TweetView一样:

?

?

[javascript]?view plaincopy?
  1. //?提供UI类dojo.provide("tweetview.SettingsView");?//?导入依赖项dojo.require("dojox.mobile.ScrollableView");dojo.require("dojo.DeferredList");dojo.require("dojo.io.script");dojo.require("tweetview._ViewMixin");?//?声明类;它继承自ScrollableViewdojo.declare("tweetview.SettingsView",?[dojox.mobile.ScrollableView,?tweetview._ViewMixin],?{?//?这里将添加方法和属性?});??

?

?

依赖项已经被导入,我们的类也已经声明完毕。

?

!该类将被被放在TweetView和_ViewMixin同一个文件夹下:js/tweetview

?

SettingsView的属性

SettingsView将有三个自定义属性。第一个是accountTemplateString:一个包含HTML标签的字符串,用以表示帐号列表中每一个列表元素的布局。

?

?

[javascript]?view plaincopy?
  1. //?模板字符串accountTemplateString:?'<img?src="${avatar}"?mce_src="${avatar}"?alt="Dojo mobile TweetView 系列课程之四 —— 创建Setting视图"?style="font-family: Consolas, 'Courier New', Courier, mono, serif; font-size: 12px; background-color: #e7e5dc; width: 687.046875px; overflow: auto; padding-top: 1px; margin: 18px 0px !important;">[javascript]?view plaincopy?
    1. //?SettingsView所引用到的TweetView视图views:?"",??

    ?

    ?

    最后一个自定义属性是serviceUrl:

    ?

    ?

    [javascript]?view plaincopy?
    1. //?用以获取用户信息的URL,这里已经提供了一个简单的URL模板serviceUrl:?"http://api.twitter.com/1/users/show/${account}.json",??

    ?

    ?

    serviceURL属性代表用来获取用户信息的Twitter服务URL。对于SettingsView来说,我们只需要获取用户的头像。

    ?

    实现SettingsView

    现在SettingsView的框架已经搭好(尽管它现在还干不了什么),是时候更新Settings视图的HTML部分了:

    ?

    ?

    [xhtml]?view plaincopy?
    1. <!--?settings?视图?--><div?id="settings"?dojoType="tweetview.SettingsView"?views="tweets,mentions">????<h1?dojoType="dojox.mobile.Heading"?fixed="top">Settings</h1>????<h2?dojoType="dojox.mobile.RoundRectCategory">Show</h2>????<ul?dojoType="dojox.mobile.RoundRectList"?class="tweetviewList"></ul></div>??

    ?

    ?

    下面是我们所做的改动:

    该控件的dojoType已经改成了我们的新类:tweetview.SettingsView。设置views属性为“tweets, mentions”;即TweetView和MentionView的ID。为RoundRectList节点添加了tweetviewList CSS类,这样该控件可以被分辨出来,并获取其引用

    当然我们需要在我们的app.html页面顶部导入tweetview.SettingsView类

    ?

    ?

    [javascript]?view plaincopy?
    1. //?使用轻量级的parserdojo.require("dojox.mobile.parser");//?导入Dojo?mobiledojo.require("dojox.mobile");//?导入额外的、非标准的dojox.mobile控件dojo.require("dojox.mobile.TabBar");//?导入兼容包dojo.requireIf(!dojo.isWebKit,"dojox.mobile.compat");//?导入TweetViewUIdojo.require("tweetview.TweetView");dojo.require("tweetview.SettingsView");//?直接在命名空间下设置tweetview账户信息tweetview.ACCOUNTS?=?{????dojo:?{?enabled:?true?},????sitepen:?{?enabled:?true?}};??

    ?

    ?

    在将SettingsView添加到app.html页面之后,是时候创建JavaScript部分了。

    ?

    SettingsView _startup()

    SettingsView类的startup方法是SettingsView工作的关键。让我们一步步看下去。首先是调用父类(dojox.mobile.ScrollableView)的startup方法来获取原本的功能:

    ?

    ?

    [javascript]?view plaincopy?
    1. //?获取?dojox.mobile.ScrollableView?的startup功能this.inherited(arguments);??

    ?

    ?

    获取视图中list控件的引用,并在添加列表元素之前隐藏它。

    ?

    ?

    [javascript]?view plaincopy?
    1. //?获取list子控件this.listNode?=?this.getListNode();//?隐藏list控件,因为它还没被填充this.showListNode(false);??

    ?

    ?

    创建一个账户数组并将它们排序,这样他们就能按字母顺序在视图中显示了

    ?

    ?

    [c-sharp]?view plaincopy?
    1. //?将帐号排序var?accounts?=?[];for(var?account?in?tweetview.ACCOUNTS)?{????accounts.push(account);}accounts.sort();??

    ?

    ?

    创建以请求Twitter用户信息返回的Deferred组成的数组:

    ?

    ?

    [javascript]?view plaincopy?
    1. //?创建一个容纳deferred的数组var?defs?=?[];//?处理每个账户dojo.forEach(accounts,?function(account){????//?请求用户信息????defs.push(dojo.io.script.get({????????callbackParamName:?"callback",????????timeout:?3000,????????//?"substitute"继承自_ViewMixin????????url:?this.substitute(this.serviceUrl,?{?account:?account?})????}));},this);??

    ?

    ?

    !你将会看到根据serviceUrl参数和一个包含账户名的对象生成URL。substitue方法继承自_ViewMixin,SettingsView也继承自该类。

    ?

    在Twitter请求触发之后,获取TweetView空间的引用:

    ?

    ?

    [javascript]?view plaincopy?
    1. //?获取视图控件this.viewWidgets?=?dojo.map(this.views.split(","),?function(id)?{????return?dijit.byId(id);});??

    ?

    ?

    剩下的功能在所有用户信息获取完毕后在dojo.DeferredList的回调函数中实现。对于每一个我们要获取信息的账户,如果账户存在并没有设置保护:

    ?

    ?

    [javascript]?view plaincopy?
    1. //?创建一个deferred列表以添加进行格式化的回调函数new?dojo.DeferredList(defs).then(dojo.hitch(this,?function(results)?{?????//?对于每个返回的用户数组...????dojo.forEach(results,?function(def,i)?{?????????//?如果deferred失败,那么用户帐号不存在或者不可用????????if(!def[0])?{????????????//?移除该帐号防止发生更多问题????????????//?同时从我们本地经过排序的账户列表中删除该账户????????????delete?tweetview.ACCOUNTS[accounts[i]];????????????delete?accounts[i];????????????return;????????}?????????//?获取用户数组????????var?user?=?def[1];?????????//?如果用户存在并且没有被冻结或是保护...????????if(user.id?&&?!user["protected"])?{?//?Protected是一个保留字?????????????//?之后这里会有更多代码?????????}?????},this);?}));??

    ?

    ?

    创建一个新的dojox.mobile.ListItem并使用我们的用户信息模板填充它:

    ?

    ?

    [javascript]?view plaincopy?
    1. //?为用户创建一个新的列表元素,附带一个开关var?item?=?new?dojox.mobile.ListItem({}).placeAt(this.listNode,?"last");?//?使用我们的模板更新元素列表内容item.containerNode.innerHTML?=?this.substitute(this.accountTemplateString,?{????user:?user.screen_name,????avatar:?user.profile_image_url,????user_id:?user.id});??

    ?

    ?

    为列表元素创建一个dojox.mobileSwitch控件,我们需要考虑账户的启用状态:

    ?

    ?

    [javascript]?view plaincopy?
    1. //?创建开关var?userSwitch?=?new?dojox.mobile.Switch({????"class":?"tweetviewSwitch",????value:?tweetview.ACCOUNTS[user.screen_name].enabled???"on"?:?"off"}).placeAt(item.containerNode,?"first");??

    ?

    ?

    为Switch控件添加onStateChange事件,在该事件中将会更新tweetview.ACCOUNTS对象的启用状态。另外,通知TweetView实例帐户的启用状态:

    ?

    ?

    [javascript]?view plaincopy?
    1. //?为开关添加change事件dojo.connect(userSwitch,?"onStateChanged",?this,?function(newState)?{????//?获取?true/false?值????var?isOn?=?newState?==?"on";?????????//?更新ACCOUNTS表????tweetview.ACCOUNTS[user.screen_name].enabled?=?isOn;?????????//?调用每一个Pane控件的onUserChange方法????dojo.forEach(this.viewWidgets,?function(viewWidget)?{????????viewWidget.onUserChange(user.screen_name,isOn);????});});??

    ?

    ?

    最后,如果我们收到了任何有效帐号,显示Settings列表节点(因为现在它已经有内容了)并刷新每一个视图。

    ?

    ?

    [javascript]?view plaincopy?
    1. //?如果我们有任何有效账户...if(accounts.length)?{????//?显示有内容的列表????this.showListNode(true);????//?出发每个视图的refresh方法????dojo.forEach(this.viewWidgets,?function(view)?{????????view.refresh();????});}??

    ?

    ?

    tweetview.Setting的JavaScript代码完成了 ——这个控件现在可以正确工作啦!不过我们还没有完成所有的JavaScript代码!我们还需要为TweetView类实现onUserChange方法。

    ?

    TweetView更新:onUserChange并从startup()中移除refresh()

    我们之所以在SettingsView中调用每个视图的refresh方法,是因为我们不想为那些确定无效的账户向Twitter发出请求。但不幸的是我们之前已经在TweetView的startup中调用了refresh方法。现在让我们移除它:

    ?

    ?

    [javascript]?view plaincopy?
    1. //?获取tweets//this.refresh();??

    ?

    ?

    SettingsView实例将会在确认一个账户是有效的时调用视图的refresh方法。

    ?

    onUserChange方法在某个账户被启用或者禁用时被SettingsView调用。我们有几种处理启用/禁用的方式:

    刷新整个控件 - 会浪费资源和Twitter API的使用率

    销毁ListItem控件,并重建它们 - 开销太大,如果用户马上又启用了账户怎么办呢? 那样会导致重新获取所有用户的tweets。这样干的话还会破坏我们的缓存功能。

    使用CSS显示/隐藏列表元素 - 就是它了!开销很小,我们已经获取了需要的数据,不需要重复获取它们!

    ?

    在TweetView中实现这一方法:

    ?

    ?

    [javascript]?view plaincopy?
    1. //?根据用户的账户启用属性更新一个tweet的显示属性onUserChange:?function(account,isOn)?{????dojo.forEach(this.getElements("user-"?+?account,this.domNode),?function(node){????????dojo[(isOn???"remove"?:?"add")?+?"Class"](node,?"tweetviewHidden");????});}??
    ?

    ?

    ?

    还记得user-{screenName} CSS类已经被分配给了tweetview.TweetView中的列表元素么?我们将使用这个CSS类来找出需要被启用/禁用的用户,并为它们移除/添加一个新的名为tweetviewHidden的CSS类,用以将一个列表元素设置为display:none或者display:block。

    ?

    设置SettingsView样式

    ?

    HTML和JavaScript部分都已经完成了,现在为我们的样式表添加一些CSS类来使得列表看起来和效果图里的一样:

    ?

    ?

    [css]?view plaincopy?
    1. /*?开关在右边?*/.tweetviewSwitch?{????right:10px;????top:10px;????float:right;}?/*?为禁用的用户隐藏对应的tweet?*/.tweetviewHidden?{????display:none;}??

    ?

    ?

    TweetView 完成了!

    tweetview.TweetView在上一篇教程中已经完成,本教程又完成了tweetview.SettingsView,我们的控件已经大功告成了!点这里来查看我们的控件。

    ?

    在本系列最后一篇教程中我们将使用Dojo的打包系统来压缩TweetView所用的JavaScript,HTML和CSS,使得整个程序更紧凑。

    ?

    ?

    http://blog.csdn.net/dojotoolkit/article/details/6535813

热点排行