Building OpenSocial Apps- P6

Chia sẻ: Thanh Cong | Ngày: | Loại File: PDF | Số trang:50

lượt xem

Building OpenSocial Apps- P6

Mô tả tài liệu
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Building OpenSocial Apps- P6: Nhà phát triển của Thư viện Series từ Addison-Wesley cung cấp hành nghề lập trình với độc đáo, tài liệu tham khảo chất lượng cao hướng dẫn về các ngôn ngữ lập trình công nghệ mới nhất và họ sử dụng trong công việc hàng ngày của họ. Tất cả các sách trong thư viện của Nhà phát triển được viết bởi chuyên gia công nghệ các học viên những người có kỹ năng đặc biệt tại các tổ chức và trình bày thông tin một cách đó là hữu ích cho các lập trình viên khác....

Chủ đề:

Nội dung Text: Building OpenSocial Apps- P6

  1. 224 Chapter 10 OSML, Gadgets, and the Data Pipeline Table 10.6 os:ActivitiesRequest Attributes Attribute Description Key Required. A string value used to identify this data within the DataContext. The key value must be unique within the app across all data tags. userId Required. A comma-delimited list of IDs to use in conjunction with the groupId attribute. Valid values are @viewer @owner a specific user ID groupId Optional. The group of users to get, relative to the value defined in the userId attribute. If this is not speci- fied, it defaults to @self, which means the person object(s) corresponding to the value of the userId attribute. Valid values are @self @friends The value @self means the records specified in the userId attribute. The value @friends means friends of the user(s) specified in the userId attribute. Fields Optional. A comma-delimited list of OpenSocial activity fields to return with each record. startIndex Optional. In a paged list of records, this specifies the starting index for results. Count Optional. An integer value specifying the maximum number of records to return. Table 10.7 os:DataRequest Attributes Attribute Description Key Required. A string value used to identify this data within the DataContext. The key value must be unique within the app across all data tags. method The REST endpoint method used for this request. Currently, only GET requests are allowed. Valid requests are people.get (equivalent to os:PeopleRequest) activities.get (equivalent to os:ActivitiesRequest) More endpoints are being added all the time, so check the MySpace developer site for the latest information. Please purchase PDF Split-Merge on to remove this watermark.
  2. OpenSocial Markup Language 225 JavaScript Blocks in OSML Apps Warning Gadget XML and OSML must be a well-formed XML document. To prevent surprise parsing errors stemming from your JavaScript code, always make use of CDATA tags in your JavaScript blocks. All apps that make use of OSML or Data Pipelining must be in gadget XML format and consist of well-formed XHTML content only. If your Content blocks wrap their innards in CDATA tags as is suggested in some of the older Gadget XML documentation, none of the OSML or Data Pipeline tags will be evaluated. As a result, your app code must consist of well-formed XHTML content only. Any JavaScript code containing a “less-than” or “greater-than” test will violate this requirement. Here is an example: if(i > 0){ ... The solution is to wrap all your JavaScript blocks in a CDATA section: // Wrapping the client script block contents with CDATA sections instructs the OSML parser to ignore things that might otherwise look like tags inside. Even though tags are not evaluated, expression language statements will be.Therefore, the following statement will still work: var greeting = "Welcome to my app, ${vwr.displayName}"; OpenSocial Markup Language The OpenSocial Markup Language, or OSML, is a tag-based markup language for adding and defining reusable user interface components, easily displaying content from an external server, and managing simple control flow.When OSML is coupled with Data Pipelining, it becomes a formidable new way of writing apps. In this section we introduce some of the basic tags available in the initial version of OSML. Please purchase PDF Split-Merge on to remove this watermark.
  3. 226 Chapter 10 OSML, Gadgets, and the Data Pipeline Table 10.8 OSML Markup Tags Tag Purpose os:Name The specified person’s display name, hyperlinked to the person’s Profile os:Badge The formatted Profile thumbnail image and name, hyperlinked to the person’s Profile os:PeopleSelector Displays a FriendPicker, scoped to the identified group Table 10.9 Remote Content Display Tags Tag Purpose os:Get Fetches the markup from an arbitrary URL via an HTTP GET request and displays it inline at the tag location myspace:RenderRequest Fetches the markup using any HTTP method supported by Contents may be displayed inline or in a specified element. Basic Display Tags There are a limited number of convenience tags defined within OSML.These tags allow simple and common UI elements to be easily rendered.The tag set is currently small, but look for more complex UI elements to be added over time.Table 10.8 identifies the cur- rent built-in OSML markup tags. Remote Content Display Tags HTML partial fragment rendering has become a common Ajax technique. OSML provides a simple tag for displaying inline content from remote servers via a GET request. MySpace also provides a more general-purpose display extension tag.Table 10.9 identifies these two tags. Control Flow Tags There are two basic mechanisms provided for display control flow: os:If and os:Repeat. Additionally, MySpace provides an extension to os:If to give it an “else” syntax as well.Table 10.10 identifies the control flow tags available in OSML Putting It Together: OSML Tic-Tac-Toe Our previous “Hello World” gadget app gave a light introduction to using Data Pipeline tags along with the general gadget structure. Now we’re going to take what we’ve seen so far and apply it to our existing Tic-Tac-Toe app to see what happens. Please purchase PDF Split-Merge on to remove this watermark.
  4. Putting It Together: OSML Tic-Tac-Toe 227 Table 10.10 OSML Control Flow Tags Tag Purpose os:If A conditional block that is shown if the expression statement evaluates to true osx:Else Inverse conditional support for os:If. This is a MySpace extension to the OSML specification. The osx:Else tag must appear immediately adjacent to an os:If tag. os:Repeat Iterates over an array of data items and displays the contents of the repeat tag, evaluated for each data item Setting Up the Gadget Our first step is to move the existing code as is into the gadget XML format. For this step we’ll make use of our desktop code editor to paste all three of the existing app surfaces into an empty gadget XML file.The OpenSocial Sandbox tool will be our best friend for validating our work in this initial stage. Creating the Initial Gadget File from Existing Code Here we will construct the initial app gadget XML source file from the code blocks we have already developed using the app Surface Editor. At the end of these steps we will have our same app in the gadget XML format. 1. Navigate to the Sandbox by clicking Tools → OSTool/Harness from the developer site and clicking the Try the Beta OpenSocial Sandbox Editor link to open the Sandbox Editor (shown in Figure 10.1). 2. Copy the contents of the Blank Sample Gadget and paste it into a new code file in your code editor (Aptana for us). 3. Change the value of the “title” attribute of the element from “Hello World” to “OpenSocial Tic-Tac-Toe.” 4. Save your file as OpenSocialTTTGadget.xml. 5. Open the source for the Home Tic-Tac-Toe surface in your code editor. 6. Copy the entire contents of the Profile code file and paste it into your new gadget in the Profile view template script.The surrounding code will look like this: // PASTE THE CODE FROM Tic-Tac-Toe HOME SURFACE HERE 7. Copy the contents of your new gadget file and paste them into the Sandbox Editor. Please purchase PDF Split-Merge on to remove this watermark.
  5. 228 Chapter 10 OSML, Gadgets, and the Data Pipeline Figure 10.1 OpenSocial Sandbox Editor. 8. Select the Home view from the Views drop-down and click Render.You will see an error similar to the following: An error occurred while parsing EntityName. Line 210, position 43. // First check if there was an error back from the proxy if(!response || (response.errors && response.errors.length > 0) || response.errorCode){ retryRequest(); } We need to fix these parsing errors before we can get any further. Fix Parsing Errors The error we encountered was caused by a greater-than comparison occurring within a JavaScript block.To get around this, we’ll wrap all client JavaScript script tag contents in CDATA sections: 1. Go back to the gadget code in your source editor. 2. Search for all the tags that do not have a type attribute of text/os-template or text/os-data. Please purchase PDF Split-Merge on to remove this watermark.
  6. Putting It Together: OSML Tic-Tac-Toe 229 Figure 10.2 Sandbox rendering of Home. 3. Add an opening CDATA tag immediately after the script tag and a closing CDATA tag immediately before the closing tag.These tags should be preceded by JavaScript inline comment characters. Here is an example of what the updated script block will look like: // 4. Save the results and re-render using the Sandbox Editor as before.When it is working correctly, you should see the Home view, rendered as in the live app (as shown in Figure 10.2). Adding Other Surfaces The other two surfaces must also be added to the gadget file. Paste the Profile and Canvas code into the templates in the appropriate Content blocks of your gadget file. Make sure you add CDATA sections to all JavaScript blocks until the Sandbox Editor can render all three surfaces without any parsing errors. There is one more issue that will surface when reconciling the existing JavaScript app with the gadget/OSML format. Activity templates make use of an expression marker in their templates that’s similar to one found in the Data Pipelining expression language. Both use the format ${SOME_VAR} to define an expression.The OSML renderer, finding the embedded activity templates, will attempt to resolve the contained tokens as Please purchase PDF Split-Merge on to remove this watermark.
  7. 230 Chapter 10 OSML, Gadgets, and the Data Pipeline expressions and hiccup.The resolution is to build up the activity template strings in a way that does not look like an expression to the server-side OSML processor. Search the gadget code for "${" and make the following changes: // Version using the default template function rsmNotification(recipient, game_id){ // Set up all the data we'll need var body = "$" body += "{sender} has finished their move "; body += "in $" body += "{app}, it's your turn!"; This splits the activity template expression up so the server doesn’t recognize it, but the template still looks the same to the client code. Reusing Common Content We have now created a single-source-file behemoth for our app, weighing in at almost 2500 lines of code. It’s nice to have a single source file for storage and tracking purposes, but it can be a bit ungainly to manage from a code maintenance standpoint.The Aptana IDE does a nice job of allowing you to expand and collapse nodes for easier visibility, but that’s no substitute for cleaning up our code.We need to DRY things out a bit. The DRY Principle The acronym DRY stands for Don’t Repeat Yourself. It’s a clever catchphrase to remind developers to reuse code as much as possible. One of the failings of using the Surface Editor for writing apps is that you will find yourself repeating the same code over and over again. With an OSML gadget an app can reuse parts of the code through the use of shared Content blocks. If we look at our code, we’ll see a lot of repeated lines across the three surfaces. In fact, putting the original Home and Profile source files in a diff tool (we used WinMerge), we find that there are only five differences, consisting of an additional style on Profile, some slightly different text on the button between the two, and a trailing div on Profile.Through the use of shared Content blocks, we can almost immediately remove 98% of the code associated with one of these surfaces. Merging Home and Profile with Shared Content Blocks Gadgets and, by extension, OSML define their different surfaces with blocks. The view attribute of a Content block identifies the surface for which the enclosed content is valid. During rendering of the OSML gadget, any and all Content blocks that Please purchase PDF Split-Merge on to remove this watermark.
  8. Putting It Together: OSML Tic-Tac-Toe 231 have a view value matching the current surface are rendered in the order in which they are encountered in the gadget XML file. If a particular block of content is valid on more than one surface, it may be identified as such by using a comma-delimited list of surface names for which it is to be rendered.This is in contrast to the app Surface Editor, which allows one and only one discrete view per surface. Our diff of the Home and Profile sources showed that there are relatively few differ- ences between the two. Since Profile seems to be a superset of the Home view, with some small textual changes, we’ll use that as the basis for both surfaces. Creating Shared Style Content Blocks One of the powers of the gadget XML format is the ability to stream shared code blocks across multiple surface views. In this section we use the notion of specifying multiple valid view values in a single Content block in order to share common markup, styles, and JavaScript between the Home and Profile surfaces. 1. Edit your app’s gadget XML file to completely delete the home Content block. 2. Change the profile Content block to also include the Home view, like this: 3. Save your changes and view them using the Sandbox tool.The Home and Profile surfaces should now match. 4. Add three new Content blocks with template script tags above the existing com- bined Home and Profile block.The first block will be used to hold the common styles.The second two will hold view-specific styles.The code should look like this: 5. Add the complete block to the first shared Content block. Please purchase PDF Split-Merge on to remove this watermark.
  9. 232 Chapter 10 OSML, Gadgets, and the Data Pipeline 6. Create new style elements in both the subsequent blocks and cut and paste the subtitle-style class definition out of the shared style area and into each private style block. Modify the Home surface’s version to be display:none; the two private style blocks should appear as shown here: .subtitle { margin:5px 0; } .subtitle { display:none; } 7. Save and view the results.The Profile surface should still show the subtitle, but the Home surface should be free of the subtitle. There is still one visible issue.The button text is incorrect on the Home view.We’ll fix that by adding some client-side JavaScript to modify the button’s text for the Home view. Customizing the Button Text Between Views There are supposed to be some minor differences between the Home and Profile views of our app. In this section we add some subtle changes in a Content block specific to the Home view that fixes the button to show appropriate text whether on the Home view or the Profile view. 1. Find the button element in the shared Profile/Home content template. It should look like this: Click here to challenge me! 2. Modify the element to add an attribute of id="playButton" to the button element. Please purchase PDF Split-Merge on to remove this watermark.
  10. Putting It Together: OSML Tic-Tac-Toe 233 3. Add a new Content block after the shared Profile/Home Content block that is specific to the Home view. Include the template script tags and client-side JavaScript script tags. // 4. Add an inline JavaScript statement to change the text of the button by manipulating the DOM: document.getElementById("playButton").innerHTML = "Click here to play now!"; 5. Save and view the results.The Home view should now show the proper button text. Here is an abbreviated code listing of the updated Home/Profile content blocks: body { background-color:#1E4C9F; color:#fff; margin:0; padding:0; } img { border:0; } ... Please purchase PDF Split-Merge on to remove this watermark.
  11. 234 Chapter 10 OSML, Gadgets, and the Data Pipeline .subtitle { margin:5px 0; } .subtitle { display:none; } ... // Please purchase PDF Split-Merge on to remove this watermark.
  12. Putting It Together: OSML Tic-Tac-Toe 235 // Working with Data Having shared display code among the surfaces is great. Having shared data is even more awesome.The next step is to start migrating some of our data calls and our display to make use of the Data Pipeline. We’ll start by changing the Viewer request to an os:ViewerRequest and use the expression language to display the Viewer info. Getting Viewer Information with os:ViewerRequest 1. Edit the canvas Content block to add a new os-data section above the os-template section.The modified code section will look like this: 2. Add a new os:ViewerRequest tag to this os-data section with the key viewer. This tag will retrieve the basic Viewer fields by default. Since our code uses several extended fields, we will specify the full field set by adding the value @all to the fields attribute. 3. Edit the contents of the myinfo div to pull the Viewer image and name from our new pipelined data stored under the viewer key in the DataContext. An expres- sion language statement is used to set the name and image URL: ... ... ${viewer.DisplayName} 4. Search for the call to printPerson in the JavaScript. It is in the getDataCallback function. Comment out this call: // printPerson(document.getElementById("myinfo")); Please purchase PDF Split-Merge on to remove this watermark.
  13. 236 Chapter 10 OSML, Gadgets, and the Data Pipeline 5. Save and view your results in the Sandbox Editor.The app will now render with the Viewer information prepopulated on the rendered surface. That’s pretty exciting.We got access to all of that information without a single line of JavaScript. Now, let’s fix the More button to show the player bio again instead of allow- ing the app to get stuck in lightbox mode. Updating the Player Bio Lightbox to Use Client-Side DataContext In this section we make some minor refactors to the existing JavaScript function that controls the display of the opponent box. At this point we only swap out some of the data calls with calls to the DataContext and leave most of the code intact. Moving to using a template will be introduced in the next chapter: Chapter 11, Advanced OSML. 1. Add a new div below the myinfo div with the ID of playerBioWrapper and set the style equal to display:none. 2. Search for the printPerson function. Notice all of the HTML being built later in the function. In the original version of this function the div element for the lightbox is created dynamically.We’re going to code the lightbox content container directly on the page. 3. Copy out the wrapping divs and close button divs. Add these to the div created in step 1.Your markup should appear like this: Player Bio close... 4. Add a new JavaScript function called showViewerBio.This holds the logic for triggering the display of the Viewer’s bio in the lightbox. 5. Add a line to this function to get the Viewer from the client DataContext: var vwr ="viewer"); 6. Build out the contents of the lightbox using the vwr object. Client DataContext objects are in JSON format and have their properties directly accessible as properties. var str = ""; str += "" str += "" str += "
  14. Putting It Together: OSML Tic-Tac-Toe 237 str += vwr.thumbnailUrl str += "' />\n"; var tryAppendLine = function(val){ if(val && val != ""){ return val + "\n"; } } str += tryAppendLine (vwr.DisplayName); str += tryAppendLine (vwr.DateOfBirth); 7. Assign the contents of your string to the innerHTML of the element internal to the player bio div and assign the entire bio contents to the lightbox: var bioElem = document.getElementById("playerBioWrapper"); var bioContents = document.getElementById("bio_contents"); bioContents.innerHTML = str; //Add to lightbox TTT.LightBox.setContent(bioElem.innerHTML); //Now show; 8. Update the More link to fire the new showViewerBio function instead of directly invoking the lightbox.Your code should properly show the lightbox again. Displaying Data Lists The next operation is to display a list of friends.This is done by combining the results of an os:PeopleRequest tag with an os:Repeat control.We’re going to update the Invite tab to use OSML and the Data Pipeline instead of client XHR requests. Displaying Friends with a Repeater A repeater allows your app to apply the same display content to multiple items in a list. The most common use case is to display a list of friends. In this section we’ll use a repeater to display the friends in the Invite tab of our app instead of the previously designed JavaScript function for manually outputting this code. 1. Add an os:PeopleRequest tag to the Data Pipeline script (text/os-data) for our Canvas view.We’ll place it under the key "friends" and get the Viewer’s friends with it.The following tag states that “I’m going to get a group of friends”—denoted by the special value "@friends" in the groupId attribute—”and these friends will be friends of the Viewer”—denoted by the special value "@viewer" in the userId attribute: Please purchase PDF Split-Merge on to remove this watermark.
  15. 238 Chapter 10 OSML, Gadgets, and the Data Pipeline 2. Find the invite_container div.We’re going to modify this div to add a repeat tag to iterate over friends. Ahead of the last closing div on this element, add the following: ${Cur.DisplayName} 3. Save and view.The Invite tab should now show all of the Viewer’s friends prepop- ulated.We leave it to the reader to rewire the client script call to rsaInviteClicked. Summary OSML is a powerful, convenient, and simple way to build apps. Operations that are tedious and repetitive with JavaScript are a snap with OSML and Data Pipelining.We’ve only just introduced some common elements, though. In the next chapter we’ll discuss some more advanced topics, such as tag templates and internationalization. The astute reader will also notice that as we ported over our Tic-Tac-Toe app to use OSML, we were not cleaning out the retired JavaScript.With the exception of com- menting out some clashing client JavaScript calls, the now unused script code is still in place. A partial listing of the retired JavaScript functions includes n getInitialData n getDataCallback n printPerson Since proper refactoring and cleanup of old code can be an arduous process, we will leave the code in place for now.We leave it to the reader to fully identify superseded code blocks and clean them out of the app. What we’ve seen so far are some of the most common operations in OSML. Remember, OSML is a late addition to the OpenSocial spec and supported starting only in version 0.9. At the time of this writing, OSML and Data Pipelining are not even fully released and aren’t recognized by previous versions, whereas the OpenSocial JavaScript API has more than a year under its belt and is fairly stable.We encourage you to push the limits with OSML, though, and give your feedback both to MySpace and to the OpenSocial community so that we may continue to improve things. Note Code listings and/or code examples for this chapter can be found on our Google Code page under Please purchase PDF Split-Merge on to remove this watermark.
  16. 11 Advanced OSML: Templates, Internationalization, and View Navigation This chapter will introduce you to someyou the more advanceddefine your own custom of techniques available to you when using OSML. After reading it, should be able to tags in your apps and use them on both the client and the server.We’ll explore directly rendering HTML fragment content from external servers and interacting with data through data listeners. And to wrap it all up, we’ll internationalize our app and localize it into different languages. OSML provides significant features beyond simple markup reuse and tag-based data declaration. In this chapter we’re going to explore some of the more advanced features of OSML.These features include defining custom tags, translating your app to different cultures and languages, and direct rendering from your external server. In the preceding chapter we covered some different ways of solving the same prob- lems we’ve previously solved, but using OSML. In this chapter we’ll do a little more of that, plus introduce some new features that open even more doors to our app. Remember, though, OSML is a very late addition to the OpenSocial spec, and it is supported beginning only with version 0.9 of the OpenSocial specification; previous versions do not recognize OSML. Inline Tag Templates Inline tag templates are reusable components that are declared directly inside the main gadget XML.They look very similar to standard inline templates with one exception: the presence of a tag attribute in the declaring template script tag.Templates defined in this manner are not rendered in place but are instead registered as custom tags for use later in the app. Please purchase PDF Split-Merge on to remove this watermark.
  17. 240 Chapter 11 Advanced OSML: Templates, Internationalization, and View Navigation Figure 11.1 Player Info box. Defining and Using a Tag Template Tag templates are an easy and convenient way to create reusable display elements. For the Tic-Tac-Toe app, we’re going to convert the Player Info box (shown in Figure 11.1) to a custom tag.This element is used for the current Viewer as well as an opponent. Our custom tag will display based on the person object passed in as a parameter. Creating the Custom Tag Template Definition The first step is to create our custom tag definition. In the following steps we’ll convert the existing Player Info box into a custom tag template for use in our app.We’ll generalize it so that it can be used for both the Viewer and the opponent. 1. Create a new template script element in the Content block of your Canvas code. This element should appear at the top of the block, before any other template scripts. In addition to the normal template script tags, it has an additional attribute of tag="my:PlayerInfo". 2. Find the Player Info box markup in our existing app gadget. It can be found by searching for the div with an ID of myinfo. Copy and paste the contents of the myinfo div into our new tag: ${viewer.displayName} More... Please purchase PDF Split-Merge on to remove this watermark.
  18. Inline Tag Templates 241 3. Now we’re going to clean out the hard-coded data and change the tag template to use parameters. Parameters are local values passed in from a tag instance.They are accessible through the reserved variable ${My}. Our tag requires that a person object be passed into the tag instance in the Player element. Replace all the ${viewer.X} statements with ${My.Player.X} statements: ${My.Player.displayName} More... 4. Add an additional borderColor parameter to specify the border color.This parameter value will be placed in an inline style in the containing div. 5. Remove the id="myinfo" attribute from the main div. Each instance tag has an individual ID, so this should not be in the template. ID values from the tag instance are carried through to the resolved tag. 6. Modify the styles to accommodate the blue/pink (male/female) background colors on this element. It would be a little tedious to do an "if" test within this markup for male/female on the My.Player object, so we’ll accommodate this feature by using style class names instead.The player_info style definition will have a blue background (default), and an additional player_info_FEMALE style will be defined to override the background to pink: .player_info { border:solid 2px black; padding:5px; background-color:#09f; } .player_info_FEMALE { background-color:#fcf; } Please purchase PDF Split-Merge on to remove this watermark.
  19. 242 Chapter 11 Advanced OSML: Templates, Internationalization, and View Navigation 7. Add an expression statement as a final CSS class name in the main div so that the gender is included in the style class name. In this way the style class name evaluates to "player_info_MALE" or "player_info_FEMALE", removing the need for any "if" checks. Using the Custom Tag Now that we’ve defined our template, the next step is to use it.We’re going to add instances of the custom tag for both the current Viewer and for the opponent, if present. 1. Search again in the code for the div with an ID of myinfo. Delete this entire div and all contained elements. 2. Add in place of the myinfo div an instance of our my:PlayerInfo tag with the id="myinfo": 3. Add in parameter elements for Player and borderColor.The Player value should be ${viewer} and the borderColor can be any valid CSS color string or color hex.We chose the color green. ${viewer} green 4. Save and view your updated app in the Sandbox Editor.The Player Info box should display as before. You can download this code and a full code listing for this chapter from our Google Code repository at trunk/chapter11. Using Client-Side Templates Custom templates are also available for use in client-side code. All your custom templates are available for use on the client side via the new opensocial.template namespace. This allows your app to create and render new template instances on the client.The call sequence looks something like this: var templateInst = opensocial.template.getTemplate("my:CustomTag"); var tdata = {} tdata["background"] = "red"; Please purchase PDF Split-Merge on to remove this watermark.
  20. Inline Tag Templates 243 tdata["otherParam"] = 1; templateInst.renderInto("target_element_id", tdata); This code creates a new instance of the tag template defined for my:CustomTag. It then builds some data to pass in to the template as local parameters and renders the instance to a target div element target_element_id. Warning Client-side templates are processed by the browser’s DOM engine. As such, they are sometimes subject to the various “features” of each DOM implementation. Some browsers attempt to perform tag balancing or add in new elements to get the markup to conform to their idea of what a proper DOM structure should look like. The net result is that templates that render perfectly on the server may not render correctly on the client. To avoid client-side template-rendering issues, use only complete DOM element blocks as a template—for example, div elements, fully enclosed tables, and the like. Avoid start- ing your templates with elements that are typically nested in other elements, such as list items (LI) and table rows (TR). Tables in particular are problematic because many browsers introduce a multitude of new elements, such as TBODY, THEAD, and TFOOT, without telling you. Favor styled div blocks in these instances. The same problem also exists with client-side repeaters and tables. If you wish to repeat a table row (TR) element, you must make use of attribute-based repeaters, not the os:Repeat element in your template. We’re going to use client templates to render the opponent’s display block using our my:PlayerInfo custom tag template. Client-Side Rendering with Custom Tags Because apps are dynamic, the information that is needed doesn’t always exist at server render time. User interactions affect the app. In our case, the opponent is selected after the initial app load.To address this, we use the templating JavaScript methods to dynamically render our custom tag after the opponent has been selected. In the following steps we will convert the opponentinfo div element from markup that required tedious editing in JavaScript code to a second implementation of our custom my:PlayerInfo template. 1. Edit the div element with an ID of opponentinfo and delete all the contents. Also remove the style class attribute so that we are left with an empty div element. 2. Add an os:PeopleSelector tag element immediately above the opponentinfo div defined in step 1. It should specify the group as the contents of our friends data item and a var="selectedOpponent" to have the selected friend placed in Please purchase PDF Split-Merge on to remove this watermark.
Đồng bộ tài khoản