GXT之旅:第六章:Templates(1)——Template(1)

来源:互联网 发布:电子地图软件开发 编辑:程序博客网 时间:2024/05/18 04:22

第六章:Templates

本章我们要了解Templates,以及学习他们是如何方便我们去自定义数据的格式化和显示。我们也会详细了解XTemplates的丰富功能

本章,我们会涉及到如下GXt功能集

  • Template
  • XTemplate
  • RowExpander
  • ListView
  • ModelProcessor
  • CheckBoxListView
之前的章节,我们学习了data-backed components 使用ModelData objects 如何自动的加载数据的。我们是通过指定其使用ModelData里面的某一列,作为显示内容。但是如果我们希望显示的内容不仅仅是一列,我们要怎么办?比如,如果我们有一个ModelData对象,里面有两列内容——first name和last name,但是我们希望显示的时候是full name(first name+last name)。

当然GXT会想到这样的问题,并且提供了连个解决方案。第一:ModelProcessor可以预加工ModelData,定义出一个新的列(以后会讲到闭嘴)。第二种就是使用Template。

首先,我们要做一些准备工作,在Feed和Item类里面加入更多的fields,并在后端的server方法里面灌入数据——以供给Template使用。

  • Feed类中,加入两个新的fields:imageUrl,存储图片的url;items用来存储Item集合。当然别忘了setter和getter方法
private String imageUrl;private List<Item> items = new ArrayList<Item>();
  • Item类加入publication和thumbnailUrl。因为是直接继承的BaseModel,所以注意getter和setter方法的书写:
package com.danielvaughan.rssreader.shared.model;import java.util.Date;import com.extjs.gxt.ui.client.data.BaseModel;@SuppressWarnings("serial")public class Item extends BaseModel {public Item() {}public String getCategory() {return get("category");}public String getDescription() {return get("description");}public String getLink() {return get("link");}public Date getPubDate() {return get("pubDate");}public String getThumbnailUrl() {return get("thumbnailUrl");}public String getTitle() {return get("title");}public void setCategory(String category) {set("category", category);}public void setDescription(String description) {set("description", description);}public void setLink(String link) {set("link", link);}public void setPubDate(Date pubDate) {set("pubDate", pubDate);}public void setThumbnailUrl(String thumbnailUrl) {set("thumbnailUrl", thumbnailUrl);}public void setTitle(String title) {set("title", title);}}
  • FeedService接口里修改原来无参数的loadFeedList()方法,为
List<Feed> loadFeedList(boolean loadItems);
  • 别忘了在FeedServiceAsync修改对应的回调方法
void loadFeedList(boolean loadItems, AsyncCallback<List<Feed>>callback);
  • FeedServiceImpl类里,通过修改loadFeedList()为loadFeedList(boolean loadItems),实现其抽象方法。
@Overridepublic List<Feed> loadFeedList(boolean loadItems)) {feeds.clear();Set<String> feedUrls = persistence.loadFeedList();for (String feedUrl : feedUrls) {feeds.put(feedUrl, loadFeed(feedUrl,loadItems)));}return new ArrayList<Feed>(feeds.values());}
  • 修改FeedServiceImpl.loadFeed方法,加入新的loadItems参数。具体实现如下:
private Feed loadFeed(String feedUrl, boolean loadItems) {Feed feed = new Feed(feedUrl);try {SAXBuilder parser = new SAXBuilder();Document document = parser.build(new URL(feedUrl));Element eleRoot = document.getRootElement();Element eleChannel = eleRoot.getChild("channel");feed.setTitle(eleChannel.getChildText("title"));feed.setDescription(eleChannel.getChildText("description"));feed.setLink(eleChannel.getChildText("link"));Element eleImage = eleChannel.getChild("image");feed.setImageUrl("");if (eleImage != null) {Element eleUrl = eleImage.getChild("url");if (eleUrl != null) {feed.setImageUrl(eleUrl.getText());}}if (loadItems) {feed.setItems(loadItems(feedUrl));}return feed;} catch (IOException e) {LOGGER.log(Level.SEVERE, "IO Error loading feed", e);return feed;} catch (JDOMException e) {LOGGER.log(Level.SEVERE, "Error parsing feed", e);return feed;}}
  • 牵扯到引用loadFeed方法的相关方法修改。
@Overridepublic void addExistingFeed(String feedUrl) {Feed loadResult = loadFeed(feedUrl, false);if (loadResult.getTitle() != null) {feeds.put(feedUrl, loadResult);persistence.saveFeedList(feeds.keySet());}}
  • 相应的loadItems方法也要修改,
@Override@SuppressWarnings("unchecked")public List<Item> loadItems(String feedUrl) {List<Item> items = new ArrayList<Item>();try {SAXBuilder parser = new SAXBuilder();Document document = parser.build(new URL(feedUrl));Element eleRoot = document.getRootElement();Element eleChannel = eleRoot.getChild("channel");List<Element> itemElements = eleChannel.getChildren("item");for (Element eleItem : itemElements) {Item item = new Item();item.setTitle(eleItem.getChildText("title"));item.setDescription(eleItem.getChildText("description"));item.setLink(eleItem.getChildText("link"));item.setCategory(eleItem.getChildText("category"));Namespace ns = Namespace.getNamespace("media","http://search.yahoo.com/mrss/");Element eleThumbnail = eleItem.getChild("thumbnail", ns);if (eleThumbnail != null) {item.setThumbnailUrl(eleThumbnail.getAttributeValue("url"));}String pubDateStr = eleItem.getChildText("pubDate");if (pubDateStr != null) {try {DateFormat df = new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z");item.setPubDate(df.parse(pubDateStr));} catch (ParseException e) {item.setPubDate(null);}}items.add(item);}return items;} catch (IOException e) {e.printStackTrace();return items;} catch (JDOMException e) {e.printStackTrace();return items;}}
  • 最后,在FeedList的onRender方法里,修改为新的service方调用
protected void load(Object loadConfig, AsyncCallback<List<Feed>>callback) {feedService.loadFeedList(false, callback);}
  • 目前为止,准备工作已经完成,下一章会在此数据结构的基础之上使用Template
  • 修改后完整的FeedServiceImpl类如下:
package com.danielvaughan.rssreader.server.services;import java.io.IOException;import java.net.URL;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.Set;import java.util.UUID;import java.util.logging.Level;import java.util.logging.Logger;import org.jdom.Attribute;import org.jdom.Document;import org.jdom.Element;import org.jdom.JDOMException;import org.jdom.Namespace;import org.jdom.input.SAXBuilder;import com.danielvaughan.rssreader.client.services.FeedService;import com.danielvaughan.rssreader.server.utils.FilePersistence;import com.danielvaughan.rssreader.server.utils.Persistence;import com.danielvaughan.rssreader.shared.model.Category;import com.danielvaughan.rssreader.shared.model.Feed;import com.danielvaughan.rssreader.shared.model.Item;import com.extjs.gxt.ui.client.data.BasePagingLoadResult;import com.extjs.gxt.ui.client.data.ModelData;import com.extjs.gxt.ui.client.data.PagingLoadConfig;import com.extjs.gxt.ui.client.data.PagingLoadResult;import com.google.gwt.dev.util.collect.HashMap;import com.google.gwt.user.server.rpc.RemoteServiceServlet;@SuppressWarnings("serial")public class FeedServiceImpl extends RemoteServiceServlet implementsFeedService {private final static Logger LOGGER = Logger.getLogger(FeedServiceImpl.class.getName());private Map<String, Feed> feeds = new HashMap<String, Feed>();private final Persistence persistence = new FilePersistence();@Overridepublic void addExistingFeed(String feedUrl) {Feed loadResult = loadFeed(feedUrl, false);if (loadResult.getTitle() != null) {feeds.put(feedUrl, loadResult);persistence.saveFeedList(feeds.keySet());}}@Overridepublic Feed createNewFeed() {UUID uuid = UUID.randomUUID();return new Feed(uuid.toString());}private PagingLoadResult<Item> getPagingLoadResult(List<Item> items,PagingLoadConfig config) {List<Item> pageItems = new ArrayList<Item>();int offset = config.getOffset();int limit = items.size();if (config.getLimit() > 0) {limit = Math.min(offset + config.getLimit(), limit);}for (int i = config.getOffset(); i < limit; i++) {pageItems.add(items.get(i));}return new BasePagingLoadResult<Item>(pageItems, offset, items.size());}@Overridepublic List<ModelData> loadCategorisedItems(String feedUrl,Category category) {List<Item> items = loadItems(feedUrl);Map<String, List<Item>> categorisedItems = new HashMap<String, List<Item>>();for (Item item : items) {String itemCategoryStr = item.getCategory();if (itemCategoryStr == null) {itemCategoryStr = "Uncategorised";}List<Item> categoryItems = categorisedItems.get(itemCategoryStr);if (categoryItems == null) {categoryItems = new ArrayList<Item>();}categoryItems.add(item);categorisedItems.put(itemCategoryStr, categoryItems);}if (category == null) {List<ModelData> categoryList = new ArrayList<ModelData>();for (String key : categorisedItems.keySet()) {categoryList.add(new Category(key));}return categoryList;} else {return new ArrayList<ModelData>(categorisedItems.get(category.getTitle()));}}private Feed loadFeed(String feedUrl, boolean loadItems) {Feed feed = new Feed(feedUrl);try {SAXBuilder parser = new SAXBuilder();Document document = parser.build(new URL(feedUrl));Element eleRoot = document.getRootElement();Element eleChannel = eleRoot.getChild("channel");feed.setTitle(eleChannel.getChildText("title"));feed.setDescription(eleChannel.getChildText("description"));feed.setLink(eleChannel.getChildText("link"));Element eleImage = eleChannel.getChild("image");feed.setImageUrl("");if (eleImage != null) {Element eleUrl = eleImage.getChild("url");if (eleUrl != null) {feed.setImageUrl(eleUrl.getText());}}if (loadItems) {feed.setItems(loadItems(feedUrl));}return feed;} catch (IOException e) {LOGGER.log(Level.SEVERE, "IO Error loading feed", e);return feed;} catch (JDOMException e) {LOGGER.log(Level.SEVERE, "Error parsing feed", e);return feed;}}@Overridepublic List<Feed> loadFeedList(boolean loadItems) {feeds.clear();Set<String> feedUrls = persistence.loadFeedList();for (String feedUrl : feedUrls) {feeds.put(feedUrl, loadFeed(feedUrl, loadItems));}return new ArrayList<Feed>(feeds.values());}@Override@SuppressWarnings("unchecked")public List<Item> loadItems(String feedUrl) {List<Item> items = new ArrayList<Item>();try {SAXBuilder parser = new SAXBuilder();Document document = parser.build(new URL(feedUrl));Element eleRoot = document.getRootElement();Element eleChannel = eleRoot.getChild("channel");List<Element> itemElements = eleChannel.getChildren("item");for (Element eleItem : itemElements) {Item item = new Item();item.setTitle(eleItem.getChildText("title"));item.setDescription(eleItem.getChildText("description"));item.setLink(eleItem.getChildText("link"));item.setCategory(eleItem.getChildText("category"));Namespace ns = Namespace.getNamespace("media","http://search.yahoo.com/mrss/");Element eleThumbnail = eleItem.getChild("thumbnail", ns);if (eleThumbnail != null) {item.setThumbnailUrl(eleThumbnail.getAttributeValue("url"));}String pubDateStr = eleItem.getChildText("pubDate");if (pubDateStr != null) {try {DateFormat df = new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z");item.setPubDate(df.parse(pubDateStr));} catch (ParseException e) {item.setPubDate(null);}}items.add(item);}return items;} catch (IOException e) {e.printStackTrace();return items;} catch (JDOMException e) {e.printStackTrace();return items;}}@Overridepublic PagingLoadResult<Item> loadItems(String feedUrl,PagingLoadConfig config) {List<Item> items = loadItems(feedUrl);return getPagingLoadResult(items, config);}@Overridepublic void saveFeed(Feed feed) {Element eleRoot = new Element("rss");eleRoot.setAttribute(new Attribute("version", "2.0"));// Create a document from the feed objectDocument document = new Document(eleRoot);Element eleChannel = new Element("channel");Element eleTitle = new Element("title");Element eleDescription = new Element("description");Element eleLink = new Element("link");eleTitle.setText(feed.getTitle());eleDescription.setText(feed.getDescription());eleLink.setText(feed.getLink());eleChannel.addContent(eleTitle);eleChannel.addContent(eleDescription);eleChannel.addContent(eleLink);eleRoot.addContent(eleChannel);persistence.saveFeedXml(feed.getUuid(), document);addExistingFeed(persistence.getUrl(feed.getUuid()));}}






原创粉丝点击