AJAX In Action [263]
RSSFeed.getFirstValue = function(element, tagName) {
var children = element.getElementsByTagName(tagName);
if ( children == null || children.length == 0 )
return "";
if ( children[0].firstChild &&
children[0].firstChild.nodeValue )
return children[0].firstChild.nodeValue;
return "";
}
This is everything we need from a Model perspective. Obviously, we could add attributes for all the optional parts of an RSS feed and populate them if they are present in the feed. We didn’t do that in this case because the RSS reader doesn’t use or need any of the optional attributes. But it’s definitely an opportunity to Licensed to jonathan zheng Refactoring 541 provide extended metadata for future features. We could also define accessor methods for the attributes to provide a more formal contract for accessing them. For example, we could write a getTitle()/setTitle() method pair for accessing the title attribute. Since JavaScript doesn’t support visibility semantics like other object-oriented languages (for example, the private/protected keywords in Java), we didn’t bother. Now let’s take a gander at our View. 13.7.2 RSS reader view With our Model classes securely in place, we can now consider a View class. We could develop a View class for the RSSFeed, and another for the RSSItem, but because our RSSReader doesn’t really view a feed independently of an item, we’ll define a single View class called RSSItemView, which encapsulates the View for an RSSItem in the context of its parent RSSFeed. Since the View in this case is obviously HTML, our View class is really just responsible for the generation of HTML. Let’s start by looking at the constructor in listing 13.25. Listing 13.25 The RSSItemView View class RSSItemView = Class.create(); RSSItemView.prototype = { initialize: function(rssItem, feedIndex, itemIndex, numFeeds) { this.rssItem = rssItem; this.feedIndex = feedIndex + 1; this.itemIndex = itemIndex + 1; this.numFeeds = numFeeds; }, } Let’s take a moment to consider the parameters. The first parameter is an instance of an RSSItem. This tells the View what Model instance it’s providing a view for. Note that it’s not generally copasetic for the Model classes to have any knowledge of the View, but the View by necessity typically has intimate knowledge of the Model. The other parameters provide some supplemental context for the View. The feedIndex tells the View which feed number it’s in. The itemIndex tells the View where this item resides within its parent RSSFeed’s array of items. The numFeeds tells the View how many feeds there are. All of these index-based parameters are for the View to indicate its place in the world, so to speak. The View might want to display a context area that indicates, for example, “this is feed Licensed to jonathan zheng 542 CHAPTER 13 Building stand-alone applications with Ajax number 1 of 7 and article number 3 of 5.” These attributes could be embedded within the Model, but they’re not really attributes that the Model should typically care about, so this context that the View needs is passed into the View constructor by the client. As mentioned previously, the responsibility of the View is to generate HTML. So our View class will need a single method that does precisely that. Let’s see what that might look like in listing 13.26. Listing 13.26 The HTML generation method toHTML: function() { var out = "" out += 'RSS Feed ' out += '(' + this.feedIndex + ' of ' + this.numFeeds + ') : '; out += ' out += ''; out += '
Return Main Page
Previous Page
Next Page