操作实例:创建博客阅读器(JavaScript 和 HTML)

此操作实例指导你如何使用拆分应用 Visual Studio 模板来创建博客阅读应用。

Important  此操作实例适用于 Microsoft Visual Studio 2012 和 Windows 8。 部分内容在 Microsoft Visual Studio 2013 Preview 和 Windows 8.1 Preview 中可能无法正常运行。

了解操作方法:

  • 定义自己的 JSON 数据
  • 使用 Windows.JS.xhr 检索 RSS 数据
  • 使用 PageControl 对象
  • ListView 中显示数据
  • 使用 AppBar 响应命令

WindowsBlogReader

在本教程中,我们为某些 Windows 团队博客创建了一个基本的阅读器。完成后的应用外观如下所示:

该项页面题为 "Windows 团队博客",并包含一个 ListView 控件(每个博客一项)。当在 ListView 中单击某项时,可以导航到所选博客的拆分页。该拆分页包含一个 ListView 控件(每篇博客文章一项),同时还包含一个控件用于纵向显示当前所选的博客文章的内容。从拆分页可以导航到项目详细信息页面,在详细信息页面中,博客文章的标题显示在顶部,当前所选博客文章的内容以水平方式显示。

在 Visual Studio 中创建新项目

为我们的应用创建一个名为 WindowsBlogReader 的新项目。以下是操作方法:

  1. 启动 Visual Studio。
  2. 在“起始页”选项卡中,单击“新建项目”。随即将打开“新建项目”对话框。
  3. 在“已安装”窗格中,展开 JavaScript 并选择“Windows 应用商店应用”模板类型。JavaScript 可用的项目模板随即将显示在对话框的中心窗格中。
  4. 在中心窗格中,选择“拆分应用”项目模板。
  5. 在“名称”文本框中,输入 "WindowsBlogReader"。
  6. 单击“确定”以创建项目。这需要花费一点时间。

下面是在解决方案资源管理器中显示的项目的结构。页面文件夹包含两组文件,一组文件用于项页面,另一组文件用于拆分页面。这些组中的每个组为 PageControl、一组 HTML、CSS 以及 JavaScript 文件,这些文件定义应用可以导航至或用作自定义控件的页面。

新项目包含创建项 PageControl 和拆分 PageControl 所需的 HTML、CSS 和 JavaScript 文件。稍后我们将为项详细信息 PageControl 添加文件。

启动我们的新 Windows 应用商店应用

如果你非常想看到基本的分隔应用的外观,请按 F5 以生成、部署并启动应用。应用显示为全屏页面,标题为 "WindowsBlogReader",包含一列示例项目,显示为网格。每个项目表示一组数据。点击或单击列表中的项目以导航至拆分页。拆分页包含两个 核心内容区域。在左侧,你可以看到与所选组关联的项目列表。在右侧,可以看到所选项目的内容。可以通过点击或单击页面上的“后退”按钮来返回项目页。

运行应用时,应用会提取 items.html 中的(或其中链接的)HTML、CSS 和 JavaScript,并将其注入到作为应用起始页的 default.html 页面中。对于在应用容器中运行的代码默认可以执行的操作有一些限制。例如,你的应用不能访问 Internet 或摄像头,除非你声明应用需要此访问权限,且用户在安装应用时授予了此访问权限。如需了解详细信息,请打开 package.appxmanifest,并转至“许可范围”选项卡。

更改标题和背景色

我们来执行两个简单的任务来自定义应用。

若要更改应用标题,请打开 items.html,然后将 itemspage 中的 h1 元素文本替换为 "Windows 团队博客",如此处所示。

 
 
 
 
  1.  
  2.     Windows Team Blogs 
  3.  

若要设置应用的背景色,请打开 default.css,并将此 background-color 属性添加到 #contenthost 中。

 
 
 
 
  1. #contenthost { 
  2.     height: 100%; 
  3.     width: 100%;     
  4.     background-color: #0A2562; 

按 F5 来生成、部署并启动此应用。请注意,项目页的标题已更改,项目页和拆分页的背景色为蓝色。

Note项目中的 images 文件夹包含默认的文件,系统将这些文件用于应用启动时应用的磁贴和初始屏幕。在本教程中,我们不更改这些内容,但是你可以按照自己的喜好使用其他图像。只 需将要使用的图像文件添加到 images 文件夹中即可。打开 package.appxmanifest,将“应用程序 UI”选项卡上“徽标”、“小徽标”和“初始屏幕”的内容替换为你的图像文件的路径。

#p#

替换示例数据

项目模板包含运行应用时看到的示例数据。我们使用这些步骤为 Windows 团队博客将这些示例数据替换为来自 ATOM 源的数据:

删除示例数据

打开 data.js,其中包含应用的示例数据。

我们不需要 generateSampleData 函数,因此你可以将它删除。

 
 
 
 
  1. // Returns an array of sample data that can be added to the application's 
  2. // data list.  
  3. function generateSampleData() { 
  4.     // Omitted code. 
  5.  
  6.          

我们不需要此代码,所以你可以将其删除:

 
 
 
 
  1. // TODO: Replace the data with your real data. 
  2. // You can add data from asynchronous sources whenever it becomes available. 
  3. generateSampleData().forEach(function (item) { 
  4.     list.push(item); 
  5. }); 

设置变量和函数

将此代码添加到 data.js(文件开头的 var list = new WinJS.Binding.List(); 声明前面)。此代码可设置我们所需的变量以及填充它们的函数。在执行本教程中的步骤时,你可以利用其中包含的注释来找到每一步放置代码的位置。

 
 
 
 
  1. // Set up array variables 
  2.  
  3. var dataPromises = []; 
  4. var blogs; 
  5.  
  6. // Create a data binding for our ListView 
  7.  
  8. var blogPosts = new WinJS.Binding.List(); 
  9.  
  10. // Process the blog feeds 
  11.  
  12. function getFeeds() {  
  13.     // Create an object for each feed in the blogs array 
  14.     // Get the content for each feed in the blogs array 
  15.     // Return when all asynchronous operations are complete 
  16.  
  17. function acquireSyndication(url) { 
  18.     // Call xhr for the URL to get results asynchronously 
  19.  
  20. function getBlogPosts() { 
  21.     // Walk the results to retrieve the blog posts 
  22.  
  23. function getItemsFromXml(articleSyndication, bPosts, feed) { 
  24.     // Get the info for each blog post 

定义博客列表

为了使这个示例简单一点,我们在 blogs 数组中包含一列硬编码的 URL。

将此代码添加到 getFeeds 函数。此代码将 JSON 数组添加到 blogs 数组。每个 JSON 数组都包含多个 JSON 对象,以存储来自源的内容。JSON 对象是名称/值对的未经排序的容器。例如,博客标题存储在一个 JSON 对象中,该对象名为 title,还有一个从 ATOM 源检索的值。使用 JSON 对象使我们将来自源的内容绑定到应用的控件变得很简单。

 
 
 
 
  1. // Create an object for each feed in the blogs array 
  2. blogs = [ 
  3.     key: "blog1", 
  4.     url: 'http://blogs.windows.com/skydrive/b/skydrive/atom.aspx', 
  5.     title: 'tbd', updated: 'tbd', 
  6.     acquireSyndication: acquireSyndication, dataPromise: null 
  7. }, 
  8.     key: "blog2", 
  9.     url: 'http://blogs.windows.com/windows/b/windowsexperience/atom.aspx', 
  10.     title: 'tbd', updated: 'tbd', 
  11.     acquireSyndication: acquireSyndication, dataPromise: null 
  12. }, 
  13.     key: "blog3", 
  14.     url: 'http://blogs.windows.com/windows/b/extremewindows/atom.aspx', 
  15.     title: 'tbd', updated: 'tbd', 
  16.     acquireSyndication: acquireSyndication, dataPromise: null 
  17. }, 
  18.     key: "blog4", 
  19.     url: 'http://blogs.windows.com/windows/b/business/atom.aspx', 
  20.     title: 'tbd', updated: 'tbd', 
  21.     acquireSyndication: acquireSyndication, dataPromise: null 
  22. }, 
  23.     key: "blog5", 
  24.     url: 'http://blogs.windows.com/windows/b/bloggingwindows/atom.aspx', 
  25.     title: 'tbd', updated: 'tbd', 
  26.     acquireSyndication: acquireSyndication, dataPromise: null 
  27. }, 
  28.     key: "blog6", 
  29.     url: 'http://blogs.windows.com/windows/b/windowssecurity/atom.aspx', 
  30.     title: 'tbd', updated: 'tbd', 
  31.     acquireSyndication: acquireSyndication, dataPromise: null 
  32. }, 
  33.     key: "blog7", 
  34.     url: 'http://blogs.windows.com/windows/b/springboard/atom.aspx', 
  35.     title: 'tbd', updated: 'tbd', 
  36.     acquireSyndication: acquireSyndication, dataPromise: null 
  37. }, 
  38.     key: "blog8", 
  39.     url: 'http://blogs.windows.com/windows/b/windowshomeserver/atom.aspx', 
  40.     title: 'tbd', updated: 'tbd', 
  41.     acquireSyndication: acquireSyndication, dataPromise: null 
  42. }, 
  43.     key: "blog9", 
  44.     url: 'http://blogs.windows.com/windows_live/b/developer/atom.aspx', 
  45.     title: 'tbd', updated: 'tbd', 
  46.     acquireSyndication: acquireSyndication, dataPromise: null 
  47. }, 
  48.     key: "blog10", 
  49.     url: 'http://blogs.windows.com/ie/b/ie/atom.aspx', 
  50.     title: 'tbd', updated: 'tbd', 
  51.     acquireSyndication: acquireSyndication, dataPromise: null 
  52. }, 
  53.     key: "blog11", 
  54.     url: 'http://blogs.windows.com/windows_phone/b/wpdev/atom.aspx', 
  55.     title: 'tbd', updated: 'tbd', 
  56.     acquireSyndication: acquireSyndication, dataPromise: null 
  57. }, 
  58.     key: "blog12", 
  59.     url: 'http://blogs.windows.com/windows_phone/b/wmdev/atom.aspx', 
  60.     title: 'tbd', updated: 'tbd', 
  61.     acquireSyndication: acquireSyndication, dataPromise: null 
  62. }]; 

#p#

检索源数据

对于此部分中的步骤,我们使用适用于 JavaScript 的 Windows 库来管理联合源。

将此代码添加到 acquireSyndication 函数。我们调用 Windows.JS.xhr 函数以检索源内容。此调用为异步调用。幸运的是,程序已经为我们处理好了在进行异步调用时可能会遇到的许多复杂问题。xhr 返回时,我们将收到结果的承诺,此承诺将返回到调用方。

 
 
 
 
  1. // Call xhr for the URL to get results asynchronously 
  2. return WinJS.xhr( 
  3.     { 
  4.         url: url, 
  5.         headers: { "If-Modified-Since": "Mon, 27 Mar 1972 00:00:00 GMT" } 
  6.                  
  7.     }); 

现在,我们将代码添加到 getFeeds 函数以调用 blogs 数组中每个博客的 acquireSyndication 函数,并添加返回到我们 promise 数组的 promise dataPromises。我们先调用 WinJS.Promise.join 函数,等待所有承诺均已满足后,再从 getFeeds 返回。这可以确保在显示 ListView 控件之前,我们拥有全部所需的信息。

 
 
 
 
  1. // Get the content for each feed in the blogs array 
  2. blogs.forEach(function (feed) { 
  3.     feed.dataPromise = feed.acquireSyndication(feed.url); 
  4.     dataPromises.push(feed.dataPromise); 
  5. }); 
  6.  
  7. // Return when all asynchronous operations are complete 
  8. return WinJS.Promise.join(dataPromises).then(function () { 
  9.     return blogs; 
  10. }); 

接下来,将此代码添加到 getBlogPosts 函数。对于 blogs 数组中的每个博客,我们针对所需的信息分析 XML 源数据。首先,我们使用 responseXML 属性以获得响应正文,然后使用 querySelector 方法以及所需的选择器来获得博客的标题和最后更新日期。我们使用 Windows.Globalization.DateTimeFormatting.DateTimeFormatter 来转换显示的上次更新日期。

如果 articlesResponse.responseXMLnull,则说明加载博客时出错,因此我们会在博客发布位置显示一条错误消息。

 
 
 
 
  1. // Walk the results to retrieve the blog posts 
  2. getFeeds().then(function () { 
  3.     // Process each blog 
  4.     blogs.forEach(function (feed) { 
  5.         feed.dataPromise.then(function (articlesResponse) { 
  6.  
  7.             var articleSyndication = articlesResponse.responseXML; 
  8.  
  9.             if (articleSyndication) { 
  10.                 // Get the blog title  
  11.                 feed.title = articleSyndication.querySelector("feed > title").textContent; 
  12.  
  13.                 // Use the date of the latest post as the last updated date 
  14.                 var published = articleSyndication.querySelector("feed > entry > published").textContent; 
  15.  
  16.                 // Convert the date for display 
  17.                 var date = new Date(published); 
  18.                 var dateFmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter( 
  19.                     "month.abbreviated day year.full"); 
  20.                 var blogDate = dateFmt.format(date); 
  21.                 feed.updated = "Last updated " + blogDate; 
  22.  
  23.                 // Get the blog posts 
  24.                 getItemsFromXml(articleSyndication, blogPosts, feed); 
  25.             } 
  26.             else { 
  27.                          
  28.                 // There was an error loading the blog.  
  29.                 feed.title = "Error loading blog"; 
  30.                 feed.updated = "Error";  
  31.                 blogPosts.push({ 
  32.                     group: feed, 
  33.                     key: "Error loading blog", 
  34.                     title: feed.url, 
  35.                     author: "Unknown", 
  36.                     month: "?", 
  37.                     day: "?", 
  38.                     year: "?", 
  39.                     content: "Unable to load the blog at " + feed.url 
  40.                 }); 
  41.  
  42.             } 
  43.         }); 
  44.     }); 
  45. }); 
  46.  
  47. return blogPosts; 

最后,将此代码添加到 getItemsFromXml 函数。首先,我们使用 querySelectorAll 来获得博客文章集以及每篇博客文章的信息。然后,我们使用 querySelector 来获得每篇博客文章的信息。我们使用 Windows.Globalization.DateTimeFormatting.DateTimeFormatter 来转换显示的上次更新日期。最后,我们使用 push 方法将每篇博客文章的信息存储在 bPosts 数组中的相应条目中。

 
 
 
 
  1. // Get the info for each blog post 
  2. var posts = articleSyndication.querySelectorAll("entry"); 
  3.  
  4. // Process each blog post 
  5. for (var postIndex = 0; postIndex < posts.length; postIndex++) { 
  6.     var post = posts[postIndex]; 
  7.  
  8.     // Get the title, author, and date published 
  9.     var postTitle = post.querySelector("title").textContent; 
  10.     var postAuthor = post.querySelector("author > name").textContent; 
  11.     var postPublished = post.querySelector("published").textContent; 
  12.  
  13.     // Convert the date for display 
  14.     var postDate = new Date(postPublished); 
  15.     var monthFmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter( 
  16.         "month.abbreviated"); 
  17.     var dayFmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter( 
  18.         "day"); 
  19.     var yearFmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter( 
  20.         "year.full"); 
  21.     var blogPostMonth = monthFmt.format(postDate); 
  22.     var blogPostDay = dayFmt.format(postDate); 
  23.     var blogPostYear = yearFmt.format(postDate); 
  24.  
  25.     // Process the content so it displays nicely 
  26.     var staticContent = toStaticHTML(post.querySelector("content").textContent); 
  27.  
  28.     // Store the post info we care about in the array 
  29.     bPosts.push({ 
  30.         group: feed, 
  31.         key: feed.title, 
  32.         title: postTitle, 
  33.         author: postAuthor, 
  34.         month: blogPostMonth.toUpperCase(), 
  35.         day: blogPostDay, 
  36.         year: blogPostYear, 
  37.         content: staticContent 
  38.     });                                          

#p#

使数据可用

现在,我们已完成了将源数据存储到数组中的代码,我们需要按照 ListView 控件的预期来对源数据进行分组。我们还需要完成将源数据绑定到 ListView 控件这一任务。

getItemsFromGroup 函数调用 createFiltered 方法,并返回指定博客的博客文章。getItemsFromGroup 函数依赖变量 list

 
 
 
 
  1. var list = new WinJS.Binding.List(); 

将此定义替换为对 getBlogPosts 函数的调用,该函数返回 blogPosts 变量。这是一个 WinJS.Binding.List 对象。

 
 
 
 
  1. var list = getBlogPosts(); 

注意,调用 createGrouped 方法将按指定的键(此情况中是指每篇文章所属的博客)对博客文章排序。

 
 
 
 
  1. var groupedItems = list.createGrouped( 
  2.     function groupKeySelector(item) { return item.group.key; }; 
  3.     function groupDataSelector(item) { return item.group; } 

更新项 PageControl

PageControl 的主要功能是使用 WinJS.UI.ListView 实现的 ListView 控件。每个博客在此列表中都有一个项目。让我们修改模板中提供的 ListView 项,以包含博客标题和上次更新博客的日期。

打开 items.html。我们需要更新此 div 标记中的 HTML,从而在我们的 blogs 数组中反映内容。

 
 
 
 
  1.  
  2.      
  3.          
  4.          
  5.              
  6.              
  7.         
 
  •     
  •  
  •  

    进行以下更新:

    1. 因为不是每个博客都有图像,因此请删除 img 标记。
    2. h6 标记中,将 textContent: subtitle 更新为 textContent: updated。这会在 ListView 项目的覆盖部分中放置上次更新日期。
    3. 移动位于类 item-overlaydiv 之前的 h4 标记。这会在 ListView 项目的主要部分中放置博客标题。

    结果如下所示。

     
     
     
     
    1.  
    2.      
    3.          
    4.                     
    5.              
    6.          
    7.      
    8.  

    若要将列表项目的颜色设置为浅蓝色,请打开 items.css 并添加此处所示的 background-color 属性。此外,在 -ms-grid-rows 属性中将第二行的大小从 90px 更改为 60px,如此处所示,因为我们只显示覆盖中的上次更新日期。

     
     
     
     
    1. .itemspage .itemslist .item { 
    2.     -ms-grid-columns: 1fr; 
    3.     -ms-grid-rows: 1fr 60px; 
    4.     display: -ms-grid; 
    5.     height: 250px; 
    6.     width: 250px; 
    7.     background-color: #557EB9; 

    若要为博客标题设置字体大小和边距,请将此代码添加到 items.css。

     
     
     
     
    1. .itemspage .itemslist .win-item .item-title { 
    2.     -ms-grid-row: 1; 
    3.     overflow: hidden; 
    4.     width: 220px; 
    5.     font-size:  24px; 
    6.     margin-top: 12px; 
    7.     margin-left: 15px; 

    更新拆分 PageControl

    打开 split.html。模板中拆分页的 HTML 使用与示例数据相同的名称。我们需要更新此 div 标记中的 HTML,从而在我们的 blogPosts 数组中反映名称。

     
     
     
     
    1.  
    2.      
    3.          
    4.          
    5.              
    6.              
    7.              
    8.          
    9.      
    10.  

    进行以下更新:

    1. 将 img 标记替换为新的
      ...
      节点。
    2. 在 h6 标记中,将 textContent: subtitle 改为 textContent: author。
    3. 删除 h4 标记

    结果如下所示。

     
     
     
     
    1.  
    2.      
    3.         
    4.           

       
    5.            |  
    6.            
    7.         
    8.          
    9.              
    10.              
    11.          
    12.      
    13.  

    注意,我们将管道字符用作分隔符,因为 HTML 不包含用于绘制竖线的标记。

    因为我们没有包含在示例数据中的所有信息,所以从 articleSection 删除此代码可以简化页面。

     
     
     
     
    1.  
    2.      
    3.          
    4.          
    5.      
    6.      
    7.  

    #p#

    若要设置文本块的颜色以及文本的项目日期、字体和边距,请打开 split.css 并添加此代码。

     
     
     
     
    1. .splitpage .itemlistsection .itemlist .item .item-date { 
    2.     -ms-grid-column:  1; 
    3.     background-color: #557EB9; 
    4.  
    5.     .splitpage .itemlistsection .itemlist .item .item-date .item-month{ 
    6.         margin-top: 12px; 
    7.         margin-left: 12px; 
    8.         margin-bottom: 4px; 
    9.         font-weight: bold; 
    10.         font-size: 28px; 
    11.     } 
    12.  
    13.     .splitpage .itemlistsection .itemlist .item .item-date .item-day{ 
    14.         margin-left: 12px; 
    15.         font-size: 28px; 
    16.     } 

    若要获取我们所需的页面布局,请将此 -ms-grid-row 属性从 "1" 改为 "2"。这导致页面标题填满整个第一行,并且将 ListView 和文章放在第二行。

     
     
     
     
    1. .splitpage .articlesection { 
    2.     -ms-grid-column: 2; 
    3.     -ms-grid-row: 2; 
    4.     -ms-grid-row-span: 2; 
    5.     margin-left: 50px; 
    6.     overflow-y: auto; 
    7.     padding-right: 120px; 
    8.     position: relative; 
    9.     z-index: 0; 

    现在,来试试再次运行应用吧。按 F5 可构建、部署并启动此应用。可以立即看到页面标题,但是应用检索源数据时有短暂的延迟。满足所有承诺后,可以看到在 ListView 中每个博客一个项。(此代码以满足承诺的顺序将这些项添加到 ListView 中。)点击或单击 ListView 中的项会将你带到拆分页,此拆分页包含所选博客的博客文章列表以及所选博客文章的内容。默认选中第一篇博客文章。

    单击“后退”箭头可返回到项页。请注意,返回到屏幕的磁贴带有过渡动画。这是 Windows JavaScript 库中的一个功能,它支持控件以及其他用户界面元素按照 Windows 应用商店应用的 UX 指南移动。

    添加项详细信息 PageControl

    项详细信息 PageControl 将博客文章的标题显示为自己的标题,并有一块区域包含博客文章的内容。

    添加项详细信息 PageControl 的步骤:

    1. 在解决方案资源管理器中,右键单击 pages 文件夹,选择“添加”>“新建文件夹”。
    2. 将该文件夹命名为 itemDetail。
    3. 在解决方案资源管理器中,右键单击 itemDetail 文件夹,选择“添加”>“新建项”。
    4. 选择“JavaScript”>“Windows 应用商店”>“页面控件”,然后使用文件名 itemDetail.html。
    5. 单击“添加”以在 pages/itemDetail 文件夹中创建 itemDetail.css、itemDetail.html 和 itemDetail.js 文件。

    打开 itemDetail.html 并更新此处所示的主要部分。此代码定义页面布局。(这是网格应用模板中包含的 itemDetail.html 页面代码的简化版本。)

     
     
     
     
    1.  
    2.  
    3.  
    4.      
    5.     itemDetail 
    6.  
    7.      
    8.      
    9.      
    10.      
    11.  
    12.      
    13.      
    14.  
    15.  
    16.      
    17.          
    18.              
    19.              
    20.                 < 本文名称:操作实例:创建博客阅读器(JavaScript 和 HTML)
      文章链接:http://www.shufengxianlan.com/qtweb/news31/411331.html

      网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

      广告

      声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联