首页 > 其他分享 >GXT之旅:第六章:Templates(1)——Template(1)

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

时间:2022-12-06 11:05:45浏览次数:37  
标签:Templates feed return Element GXT feedUrl Template new import


第六章: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),实现其抽象方法。
@Override
public 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方法的相关方法修改。
@Override
public 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 implements
FeedService {

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();

@Override
public void addExistingFeed(String feedUrl) {
Feed loadResult = loadFeed(feedUrl, false);
if (loadResult.getTitle() != null) {
feeds.put(feedUrl, loadResult);
persistence.saveFeedList(feeds.keySet());
}
}

@Override
public 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());

}

@Override
public 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;
}
}

@Override
public 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;
}
}

@Override
public PagingLoadResult<Item> loadItems(String feedUrl,
PagingLoadConfig config) {
List<Item> items = loadItems(feedUrl);
return getPagingLoadResult(items, config);
}

@Override
public void saveFeed(Feed feed) {
Element eleRoot = new Element("rss");
eleRoot.setAttribute(new Attribute("version", "2.0"));

// Create a document from the feed object
Document 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()));
}
}







标签:Templates,feed,return,Element,GXT,feedUrl,Template,new,import
From: https://blog.51cto.com/u_15903664/5915153

相关文章