四、使用 HTML 和 JavaScript 构建自定义 Web 部件

与脚本编辑器 Web 部件相结合的内容编辑器 Web 部件允许您在自己的环境中快速构建解决方案。虽然这种组合无疑为您提供了开发解决方案的选择,但它不是一个容易扩展或重用的解决方案。您可能会发现它适合您对简单的单页解决方案的需求,但是一旦您的需求变得更加复杂,您会发现该解决方案在许多方面都有局限性。幸运的是,你在前一章学到的东西可以扩展成更健壮的解决方案。

在本章中,你将学习如何使用 Etherson 方法构建健壮的、可重用的 web 部件。这种方法仍然适用于 HTML 和 JavaScript,扩展了上一章的内容。您将看到如何更好地组织您的代码,以及这种方法如何允许您处理您能想到的任何定制解决方案。

埃瑟森方法

在过去的几年里,我有幸在许多激动人心的 SharePoint 项目中担任顾问。此外,我还能与一些最有才华的人一起工作,他们每天都在鞭策我。其中一个人是迈克·埃瑟里格德。Mike 和我开发了一个面向公众的 SharePoint 2010 网站,该网站需要响应移动设备。它还需要连接到未集成到 SharePoint 中的外部数据库。迈克的解决方案是构建可以通过 JavaScript 调用的定制 WCF web 服务。这些服务随后与定制的 HTML 和 JavaScript 一起被部署到服务器上。HTML 是通过放置在每个页面上的 XML 查看器 Web 部件来使用的。

这个解决方案非常有效。它易于开发和快速部署。它允许我们轻松地将服务器上的数据集中在一起,并将其返回到我们的页面,并且可以轻松地从 SharePoint 服务器提供 HTML。这在 SharePoint 2010 中工作得很好,在 SharePoint 2013 中也会很好,但在 SharePoint Online 中不行,因为那里不能部署任何服务器端代码。幸运的是,由于微软扩展了 JavaScript 对象模型和 REST API,该解决方案可以被调整以允许服务器之外的完整开发生命周期——于是 Etherson 方法诞生了。

Etherson 方法由以下组件组成:

  • 文档库
  • 文件夹
  • 内容编辑器 Web 部件
  • HTML、JavaScript 和 CSS

如您所见,该解决方案只需要几个组件就能产生巨大影响。乍一看,您可能会想,如何用这么简单的一组项目构建健壮的解决方案呢?这种方法的真正强大之处在于它的简单性以及 JavaScript 对象模型和 REST API 的强大功能。让我们详细看看每个组件。

文档库

这种方法的核心是一个文档库。该库将作为自定义 web 部件中使用的所有代码的主存储库。所有代码都将存储在该库中,每个 web 部件都有一个文件夹。如果符合您的需要,您可以使用多个库。例如,您可以在网站集的根目录下有一个库,用于您的所有子网站。您可以更细化,在每个子网站中放置一个仅用于该网站的库。您可以非常灵活地构造它,因为它只是一个放置代码的地方。

设置库需要以下步骤:

Create a new document library.   Turn off search indexing.   Turn on versioning.   Place unique permissions on the library.  

首先,我们将简单地创建一个现成的文档库,并将其命名为 Webparts,如图 4-1 所示。

A978-1-4842-0544-0_4_Fig1_HTML.jpg

图 4-1。

A new out-of-the-box document library for our code

这没什么特别的:我们只是通过设置菜单使用添加应用选项并选择文档库来添加它。接下来,我们将确保搜索引擎不会索引这个库。这样做的原因是该库将用于存储代码。普通用户没有必要看到这段代码,因为它是用来呈现自定义 web 部件的;因此,让它出现在搜索结果中会混淆用户的搜索体验。关闭搜索索引将确保代码文件不出现在搜索结果中。从功能区进入库设置,选择高级设置,如图 4-2 所示。

A978-1-4842-0544-0_4_Fig2_HTML.jpg

图 4-2。

Accessing the Advanced Settings page in the Library Settings

在“高级设置”页面上,您会发现文档库有许多选项。在页面中间寻找搜索标题。只有两个选项:允许或不允许项目出现在搜索结果中。点击否,如图 4-3 所示。

A978-1-4842-0544-0_4_Fig3_HTML.jpg

图 4-3。

Turning off the search indexing for the document library

滚动到页面底部,然后单击确定保存您的更改。您将返回到设置页面,在这里您可以继续进行版本控制。版本控制很重要,因为它允许轻松回滚代码。如果您需要实现对现有代码的更改,这可以让您安心。例如,假设您已经开发了一个满足当前业务需求的解决方案,并且一切都运行良好。你被要求做一个大的改变并开发新的代码来满足需求。你测试你的代码,一切看起来都很好。您上传了更改——用户立即开始抱怨出了问题!你忘记了在不同的浏览器中测试,你的代码对每个使用 Chrome 的人来说都是错误的。

如果打开了版本控制,只需转到文档库并恢复以前的代码文件。就这样,用户看到了之前的代码,至少一切又正常了。正如您所看到的,拥有快速、轻松地回滚代码更改的能力在开发过程中的某个时刻会非常有帮助。

要打开版本控制,点击版本控制设置链接,如图 4-4 所示。

A978-1-4842-0544-0_4_Fig4_HTML.jpg

图 4-4。

Accessing the Versioning Settings for the document library

进入版本设置页面后,点击文档版本历史标题下的创建主要版本选项,如图 4-5 所示。您还可以创建主要版本和次要版本;然而,对于这本书,我们将保持简单,只使用主要版本。

A978-1-4842-0544-0_4_Fig5_HTML.jpg

图 4-5。

Turning on Create Major Versions in the document library

滚动到页面底部,单击确定保存更改。您将返回到设置页面,在这里您可以转到权限。

Note

根据您创建的网站类型,您可能会发现版本控制已经打开。例如,打开了发布基础结构的发布门户或团队站点已经打开了版本控制。在任一情况下,打开“版本控制设置”页面以确保它已打开。

最后,您必须通过应用独有权限来保护文档库。我们希望保护这个库,以控制谁可以添加或修改其中的代码。用户需要具有读取权限,以便可以将代码加载到 web 部件中;但是您只希望开发人员拥有 contribute 访问权限。这一点至关重要,因为您只希望一小部分人能够上传代码并有可能删除代码。要修改权限,点击“该文档库的权限”链接,如图 4-6 所示。

A978-1-4842-0544-0_4_Fig6_HTML.jpg

图 4-6。

Accessing the permissions settings for the document library

单击此链接会将您带到文档库的权限页面。要应用独有权限,点击功能区中的停止继承权限按钮,如图 4-7 所示。

A978-1-4842-0544-0_4_Fig7_HTML.jpg

图 4-7。

The Permissions tab in the Ribbon for the document library

通常,SharePoint 中的所有项目都继承其父项目的权限。当您创建此新文档库时,默认情况下,它拥有所在网站的权限。如果您选择停止继承权限,SharePoint 确实希望确保这是您的意图,并通过确认对话框提示您,如图 4-8 所示。

A978-1-4842-0544-0_4_Fig8_HTML.jpg

图 4-8。

Confirmation dialog when breaking permissions

单击“确定”确认更改,您将返回到“权限”页面。你会注意到功能区现在有了一些额外的选项,最明显的是 Grant Permissions 按钮,如图 4-9 所示。您将使用“授予权限”选项在中添加权限。

A978-1-4842-0544-0_4_Fig9_HTML.jpg

图 4-9。

Grant permissions using the Grant Permissions button in the Ribbon Note

一旦停止继承权限,您应该删除列表中当前的所有用户和组。即使您破坏了权限,以前的用户和组仍将保留,除非手动删除。

点击“授予权限”按钮会打开“共享”对话框,在这里您可以选择要授予谁权限,如图 4-10 所示。对话框中的第一个文本框允许您指定哪些用户或组可以访问该库。在这一步中,您希望授予每个人读权限。当您在文本框中键入内容时,SharePoint 会提供一个自动完成的人员和组列表供您选择。键入 Everyone,然后从建议列表中选择它。

A978-1-4842-0544-0_4_Fig10_HTML.jpg

图 4-10。

Granting Read access to all users

您可以单击“显示选项”链接来展开对话框,并查看可用的其他选项。您可能希望取消选中发送电子邮件邀请选项,尤其是在添加大型群组时。在这种情况下,它会向有权访问 SharePoint 的每个人发送一封电子邮件,这可能不是一个好主意。另一个选项是“选择权限级别”下拉列表;选择“读取”,因为我们希望每个人都拥有特定级别的访问权限。

单击共享按钮保存自定义权限。此时,所有用户都拥有对库的读取权限。对所有开发人员重复这些步骤,并授予他们 Contribute 权限级别。通过这种方式,这些用户可以上传新代码并修改库中现有的代码。

Note

如果您使用的是只有少数人访问的开发环境或站点,则可以跳过应用独有权限。这在 QA 或生产环境中是至关重要的,但是在这里开发环境可以不那么严格。

既然已经创建并配置了文档库,我们可以继续处理其他组件,如文件夹。除了为您的解决方案编写代码之外,使用 Etherson 方法建立文档库是最大的任务。相比之下,其余的组件似乎很简单。

文件夹

使用这种方法,每个自定义 web 部件都有一个文件夹,其中包含该 web 部件所需的所有文件。您也可以有一个集中的文件夹,其中包含所有 web 部件共享的脚本。例如,如果您想在一个文件夹中存储一份 jQuery,您可以避免通过母版页添加它,而只让每个 web 部件从中心文件夹引用它。您可能还有一些工具脚本,用于执行多个 web 部件的通用功能。无论需要什么,一个中心文件夹可能会派上用场。

导航到您在上一节中创建的 web 部件文档库。使用菜单中的新建命令,从上下文菜单中选择新建文件夹,如图 4-11 所示。

A978-1-4842-0544-0_4_Fig11_HTML.jpg

图 4-11。

Creating a new folder

创建一个新文件夹并将其命名为 Simple Example。我们将使用这个文件夹来存放第一个示例的 HTML 和 JavaScript。此时,Webparts 文档库中应该只有一个文件夹。随着阅读本书的深入,您将添加更多文件夹;但目前来看,这是一个好的开始。

HTML、JavaScript 和 CSS

现在我们有了一个文档库和一个存放代码的文件夹,让我们把 HTML 文件和 JavaScript 文件放在一起。在本节中,我们将使用 Visual Studio 编写代码并构建 HTML 和 JavaScript 文件。如果你在第一章安装了 Visual Studio 速成版,你就一切就绪了。你可以使用任何你喜欢的代码编辑器——甚至记事本!启动 Visual Studio,点击【文件】➤新建➤文件,新建一个文件,如图 4-12 所示。

A978-1-4842-0544-0_4_Fig12_HTML.jpg

图 4-12。

Creating a new file in Visual Studio

这将打开一个新的对话框,您可以在其中选择想要创建的文件类型。这里有很多选择,但我们要找的那个就在前面。从列表中点击 HTML 页面,然后点击打开,如图 4-13 所示。

A978-1-4842-0544-0_4_Fig13_HTML.jpg

图 4-13。

Creating a new HTML page from the New File dialog

单击“打开”后,将会创建并显示一个新的 HTML 文件。如果您是 Visual Studio 的新手,您将很难体会到代码编辑器带给您的效率。新创建的 HTML 文件已经为你生成了一些代码,如图 4-14 所示。

A978-1-4842-0544-0_4_Fig14_HTML.jpg

图 4-14。

Newly created HTML file with code

如果您要保存此文件并将其加载到 SharePoint 中,它不会显示任何内容,因为在浏览器中没有内容呈现给用户。然而,它是一个完全有效的 HTML 文件!虽然这并没有给人留下太深刻的印象,但是您会发现 Visual Studio 在您编写代码时会提供很多类似的帮助。

对于这个例子,我们将从使用第 3 章中的代码开始,除了我们将代码分成一个 HTML 文件和一个 JavaScript 文件。首先将下面一行添加到新的 HTML 页面中:

<div id="divHelloWorld">Hello World!</div>

将这条线放在两个<body>标签之间,如图 4-15 所示。

A978-1-4842-0544-0_4_Fig15_HTML.jpg

图 4-15。

New HTML file with code from the previous chapter

现在让我们创建一个 JavaScript 文件来托管我们的脚本。像以前一样,从菜单中选择文件➤新➤文件。当“新建文件”对话框打开时,您会注意到没有列出用于创建新 JavaScript 文件的选项。为此,我们需要从左侧导航栏中选择“Web ”,以查看网站的所有文件模板。滚动到所列模板的底部,你会找到 JavaScript 文件模板,如图 4-16 所示。

A978-1-4842-0544-0_4_Fig16_HTML.jpg

图 4-16。

JavaScript file option in the New File dialog

一旦创建了新的 JavaScript 文件,您会注意到它看起来与您之前创建的 HTML 文件非常不同。实际上是完全空白的,如图 4-17 所示。

A978-1-4842-0544-0_4_Fig17_HTML.jpg

图 4-17。

New JavaScript file created in Visual Studio

与 HTML 文件一样,您将使用第 3 章示例中的相同代码。将以下代码放入刚刚创建的新 JavaScript 文件中:

$(function() {

$.ajax({

url: "/apress/_api/web/lists/GetByTitle('Demo List')",

type: "GET",

headers: {

"accept": "application/json;odata=verbose"

},

}).success(function(data) {

$("#divHelloWorld").html(data.d.Title + " : " + data.d.Created);

});

});

Note

在本书的所有代码示例中,URL 都是针对我的环境的,其中包括一个根网站集和一个名为 Apress 的子网站,我的所有代码都驻留在那里。因此,我的所有 URL 将显示为“/apress/…..”。您应该相应地更新您的代码部署的 URL,以及您的站点的结构。

你会注意到不像在第 3 章的例子中,你没有开始和结束<script></script>标签来包装你的代码。由于代码是由扩展名为.js的 JavaScript 文件提供的,浏览器不需要被告知这是一个带有这些标签的脚本,如图 4-18 所示。

A978-1-4842-0544-0_4_Fig18_HTML.jpg

图 4-18。

JavaScript code in Visual Studio

现在这两个文件都已创建,您将保存它们。将这些文件保存在计算机上您喜欢的任何位置。将 HTML 文件命名为 SimpleExample.js,将 JavaScript 文件命名为 SimpleExample.js。保存文件后,我们现在需要将 JavaScript 文件连接到 HTML 文件,以便代码能够正确运行。为此,我们需要向 HTML 文件添加一个 JavaScript 引用,类似于下面的代码行:

<script type="text/javascript" src="/apress/webparts/Simple Example/SimpleExample.js"></script>

在我的环境中,我有一个名为 Apress 的子网站,这是我的 web 部件文档库所在的位置。这个脚本引用以一个/开头,意思是使用站点的根 URL。接下来,我们放置子网站名称、文档库名称、文件夹名称,最后是脚本文件名。根据您设置环境的方式,您可能不需要子网站引用,或者它的名称可能有所不同。

将脚本引用放在 HTML 文件的<head>中,如图 4-19 所示。

A978-1-4842-0544-0_4_Fig19_HTML.jpg

图 4-19。

The HTML file with the script reference added in

用新的脚本引用保存SimpleExample.html文件。接下来,您将把这两个文件上传到您在文档库中创建的简单示例文件夹中,如图 4-20 所示。

A978-1-4842-0544-0_4_Fig20_HTML.jpg

图 4-20。

HTML and JavaScript files uploaded to the Simple Example folder

此时,使用 Etherson 方法,您已经创建并上传了重新创建第 3 章中的示例所需的两个文件。如果您有一个更复杂的解决方案,您可以想象这个文件夹包含几个 JavaScript 文件、CSS 文件,可能还有多个 HTML 文件。这完全取决于你的需求是复杂还是简单。接下来,让我们看看如何使用内容编辑器 Web 部件来使用这些文件。

内容编辑器 Web 部件

现在我们已经有了呈现某些内容所需的文件,让我们在页面上放置一个 CEWP 并使用它们。我们将使用第 3 章示例中的相同站点和页面。如果您的页面上还有 CEWP 和 SEWPs,请继续删除它们,使页面为空。将页面置于编辑模式,然后在页面上插入一个新的 CEWP。保存页面—我们稍后将回到此 web 部件。

导航回 web 部件文档库并打开简单示例文件夹。右键单击SimpleExample.html文件,从菜单中选择复制链接位置,如图 4-21 所示。

A978-1-4842-0544-0_4_Fig21_HTML.jpg

图 4-21。

Copying the location of the HTML file

根据您使用的浏览器,此选项的标题可能会有所不同。例如,如果使用 Internet Explorer,您可以选择复制快捷方式。无论您使用哪种浏览器,右键单击都会显示将 URL 复制到文件的选项。一旦您复制了它,您就可以导航回带有 CEWP 的页面。

将页面置于编辑模式,然后将 CEWP 置于编辑模式。就像在第三章中一样,在 CEWP 工具窗格中,第一个属性是标题内容链接。将您复制的网址粘贴到该文本框中,如图 4-22 所示。

A978-1-4842-0544-0_4_Fig22_HTML.jpg

图 4-22。

The URL to the SimpleExample.html file in the CEWP Content Link property

与第 3 章中的例子不同,由于这个 HTML 包含了对 JavaScript 文件的引用,我们需要做的就是将文件的 URL 放入内容链接属性中。当 HTML 文件加载时,JavaScript 文件也会加载。本例中不需要脚本编辑器 Web 部件。单击确定,然后保存页面。当它重新加载时,HTML 文件将呈现如图 4-23 所示。

A978-1-4842-0544-0_4_Fig23_HTML.jpg

图 4-23。

SimpleExample.html file rendered in the Content Editor Web Part

此时,您可能想知道为什么要执行如此多的设置和配置,因为使用 CEWP 和 SEWP 可以更快地产生结果。随着实际解决方案越来越多,使用 Etherson 方法的好处变得越来越明显。例如,假设您需要开发一个定制的解决方案,该解决方案聚合用户正在跟踪的任务和文档,并将它们放入一个链接列表中,供用户单击以查看项目。它将部署在网站集中每个部门子网站的主页上。使用 CEWP/SEWP 解决方案,您不仅需要将代码粘贴到每个页面上,如果以后需要对解决方案进行更改,您还需要更新该代码的所有实例。这可能是一个相当大的挑战。使用 Etherson 方法,您仍然在每个站点中添加一个 CEWP,但是只引用一组代码文件。如果需要更改,您只需要在一个地方更新代码。这更容易管理。

这种方法的另一个好处是 CEWP 可以为您执行一些错误处理。如果由于某种原因 HTML 文件不再可用(可能被移动或删除),CEWP 可以向用户显示一条友好的消息。为了演示这一点,让我们从 CEWP 中删除内容链接,然后单击 Apply 按钮。web 部件中的内容将被删除,留给您一个空白的 CEWP,如图 4-24 所示。

A978-1-4842-0544-0_4_Fig24_HTML.jpg

图 4-24。

Content Editor Web Part after the Content Link has been removed

此时,您已经基本上将 CEWP 恢复到了添加时的初始状态。单击 web 部件中间的“单击此处添加新内容”链接。您会注意到 web 部件中出现了一个光标,您可以在其中直接键入文本。在这里,您将添加文本抱歉,我们遇到了一个错误。接下来,你将把SimpleExample.html的链接添加回内容链接属性,如图 4-25 所示。

A978-1-4842-0544-0_4_Fig25_HTML.jpg

图 4-25。

Plain text and Content Link URL placed in the Content Editor Web Part

单击确定,然后保存页面。您会注意到 web 部件看起来与您仅使用内容链接属性时完全一样。不显示纯文本消息,而是呈现 HTML 页面中的内容。CEWP 将总是尝试使用添加到内容链接属性的任何 URL,而不是显示它可能有的任何纯文本。现在,让我们从简单示例文件夹中删除 HTML 和 JavaScript 文件,如图 4-26 所示。

A978-1-4842-0544-0_4_Fig26_HTML.jpg

图 4-26。

HTML and JavaScript files deleted from the Simple Example folder

一旦 HTML 文件被删除,CEWP 将不再能够加载它;它不见了。通过在 web 部件中提供纯文本,它现在将显示您加载的错误消息,如图 4-27 所示。

A978-1-4842-0544-0_4_Fig27_HTML.jpg

图 4-27。

The plain-text message displayed when the web part could not load the HTML file

您可能希望对开发工作中的错误进行编码,但是这种内置于 CEWP 中的回退是一个很好的选择,以防出现其他错误。你应该总是以这种方式提供一些内容。在许多情况下,CEWP 无法访问您的 HTML 文件,例如:

  • 文件从文件夹中删除(就像我们刚才做的那样)
  • 出现网络错误
  • 您在内容链接属性中手动键入 URL,并且拼错了文件名

为了以防万一,最好还是利用这个功能。现在让我们更新前一个例子中的代码,不仅仅是显示一个列表名称。

使用列表数据

前面的例子向您介绍了 Etherson 方法。此时,您已经有了一个 HTML 文件和一个 JavaScript 文件,它们提取并显示关于列表的数据。不算太坏,但显然这不是你在现实世界的解决方案中会做的事情。因此,让我们扩展这段代码,从列表中提取一些数据并显示给用户。如果你还没有,将一些数据放入你的演示列表,如图 4-28 所示。

A978-1-4842-0544-0_4_Fig28_HTML.jpg

图 4-28。

The Demo List with a few items populated in it

此时,列表中的项目并不重要;我们只是需要一些数据来提取和显示。您可以随意摆放物品;我们要把他们都抓起来。现在我们在列表中有了更多的数据,我们将更新前面的SimpleExample.js文件,以便我们请求列表项,而不是关于列表的数据。用以下内容更新您的代码:

$(function () {

$.ajax({

url: "/apress/_api/web/lists/GetByTitle('Demo List')/items",

type: "GET",

headers: {

"accept": "application/json;odata=verbose"

},

}).success(function (data) {

var listItemInfo = ";

$.each(data.d.results, function (key, value) {

listItemInfo += "<strong>Title: </strong>" + value.Title + " <strong>Description: </strong>" + value.Description + "<br />";

});

$("#divHelloWorld").html(listItemInfo);

});

});

它看起来与前面的代码相似,但是添加了一些关键的东西。首先,AJAX 调用中的 URL 已经更新,在末尾包含了/items:

url: "/apress/_api/web/lists/GetByTitle('Demo List')/items"

我们仍然调用同一个列表,但是我们需要让 REST API 知道我们这次想要列表中的项目。通过提供/items而不提供其他信息,我们告诉 API 返回列表中的所有项目。

Note

除非你确信你的列表中不会有太多的数据,否则你不应该在任何数据调用中请求所有的条目。您可以通过提供限制器或 CAML 查询来提供限制返回数据的方法,该查询将只返回您正在寻找的项目。我们将在本书后面更深入地探讨这些选项。

在 JavaScript 的 success 函数中,我们将遍历返回的所有数据:

var listItemInfo = ";

$.each(data.d.results, function (key, value) {

listItemInfo += "<strong>Title: </strong>" + value.Title + " <strong>Description: </strong>" + value.Description + "<br />";

});

我们从一个名为listItemInfo的新空变量开始。这个变量用于保存我们在循环 API 调用结果时构建的所有 HTML。接下来,我们使用一个内置的 jQuery 函数each来遍历结果。通过使用$.each,我们说对于data.d.results对象中的每一项,执行下面的函数。在您的定制解决方案中,您会经常用到这个函数,因为遍历列表项是非常常见的。

就像我们简单显示列表的属性和数据的例子一样,我们看到了熟悉的data.d对象。但是,这次我们有了一个新的属性,叫做results。当我们查询该列表的数据时,我们需要的所有信息都在d属性下找到;比如说,d.Title。当你请求列表项时,所有的数据都会在results属性中找到。

each函数中,我们将listItemInfo变量设置为获取当前列表项标题和描述的 HTML。使用+=语法,我们将变量设置为当前值加上新值。这是一个简单的添加到 HTML 的方法,如果有来自前面的循环的话。循环完成后,我们将 HTML 设置为 Hello World DIV:

$("#divHelloWorld").html(listItemInfo);

4-29 显示了 Visual Studio 中的完整文件。

A978-1-4842-0544-0_4_Fig29_HTML.jpg

图 4-29。

The updated SimpleExample.js file in Visual Studio

用更新的代码保存文件。在将它上传到文档库之前,让我们快速更改一下 CEWP 的标题,这样这个例子就更加真实了。导航回放置 web 部件的页面,并将其置于编辑模式。展开外观手风琴并更新标题属性,如图 4-30 所示。

A978-1-4842-0544-0_4_Fig30_HTML.jpg

图 4-30。

Updating the title of the Content Editor Web Part

单击“确定”,然后保存该页面。将更新后的SimpleExample.js文件上传到 Webparts 文档库中的简单示例文件夹。将出现一个对话框,询问您是否要替换当前文档;单击确定。埃瑟森方法的优点仍然有效;因为您在文档库中打开了版本控制,所以您可以轻松地替换文件。如果弄错了,可以恢复之前的版本!导航回你的页面,你会看到更新后的代码抓取列表项并显示出来,如图 4-31 所示。

A978-1-4842-0544-0_4_Fig31_HTML.jpg

图 4-31。

Updated JavaScript fetching list items

结合更新的标题,这个 CEWP 现在更像一个现实世界的解决方案!当然,我们在这里真正做的只是重新创建一个现成的列表视图 Web 部件,但是它应该已经展示了使用 HTML 和 JavaScript 开始处理 SharePoint 数据是多么容易。接下来,让我们继续看看 Etherson 方法的一些好处。

使用版本控制回滚更改

在本章的前面,当您创建文档库来保存自定义代码时,您启用了版本控制。在开发过程中的某个时刻,你会在编写代码时犯错误,而它会通过测试。这发生在我们所有人身上,是不可避免的。幸运的是,打开版本控制后,如果发生这种情况,您可以快速回滚更改。您可能会发现,仅仅因为用户对您代码的最新版本不满意,您就需要回滚。不管什么原因,都是又快又容易。

当您上传新版本的SimpleExample.js文件时,系统会询问您是否要替换现有版本。通过单击“确定”,您在库中创建了该文件的新版本。由于版本控制是打开的,您只需点击几下就可以恢复以前的版本。导航到简单示例文件夹,点击SimpleExample.js文件的菜单,如图 4-32 所示。

A978-1-4842-0544-0_4_Fig32_HTML.jpg

图 4-32。

Accessing the Version History on a file

菜单打开后,您需要访问二级菜单,在那里您可以找到版本历史选项。点击这个选项,你会看到一个对话框,显示文件的所有版本。此处显示的版本数量取决于您设置库的方式。例如,如果您将版本数量限制为五个,您将只能在这里看到五个以前的版本。选择您想要的版本;在这种情况下,它将是列表中的第二个版本。版本从上传日期开始按升序排列。使用菜单选项,从菜单中选择恢复,如图 4-33 所示。

A978-1-4842-0544-0_4_Fig33_HTML.jpg

图 4-33。

Restoring a previous version on the file

当您单击“还原”选项时,会出现一个确认对话框,提示您“您将要用所选版本替换当前版本”单击确定确认恢复,屏幕将刷新。新版本被添加到列表中。使用 CEWP 导航回您的页面并刷新页面。您可能需要通过按键盘上的 Ctrl+F5 来执行硬刷新;这将指示浏览器从服务器加载 JavaScript 文件的新副本。结果应该是加载列表数据的前一个脚本,如图 4-34 所示。

A978-1-4842-0544-0_4_Fig34_HTML.jpg

图 4-34。

Restored file being displayed in the Content Editor Web Part

这里需要注意的一点是,虽然脚本内容已经更新,但是 web 部件的标题保持不变。由于这是拼图的两个独立部分,恢复脚本文件对 web 部件本身没有任何影响!

使用 Firebug(开发人员工具)调试

当你为任何东西写代码时,不管是工具、语言还是环境,你都需要能够调试它。简单地说,停止代码运行,一行一行地查看有什么数据进来,以及代码是如何处理的。由于 Etherson 方法利用 HTML 和 JavaScript,您可以使用 Firebug 或开发工具在浏览器中轻松调试代码。正如在第一章中提到的,我们将使用 Firebug——Firefox 的一个插件。您可以在任何浏览器中使用内置的开发工具。要启动这些工具,只需按键盘上的 F12 键,工具就会在屏幕下方启动,如图 4-35 所示。

A978-1-4842-0544-0_4_Fig35_HTML.jpg

图 4-35。

Firebug console window in Firefox

如果尚未打开,请在 Firebug 中选择脚本选项卡。如果这是您第一次启动 Firebug,您可能需要通过下拉选项卡上的箭头并在选项中选择 Enabled 来启用脚本调试。此选项卡允许您检查正在为页面加载的所有脚本。左侧窗格显示您正在查看的当前脚本,右侧窗格显示任何已加载的 JavaScript 对象。这些对象位于右窗格的“监视”选项卡下。让我们使用左窗格正上方的下拉列表打开我们的SimpleExample.js脚本,如图 4-36 所示。

A978-1-4842-0544-0_4_Fig36_HTML.jpg

图 4-36。

Locating the SimpleExample.js file in Firebug

该列表包含为页面加载的所有 JavaScript 文件。向下滚动直到找到SimpleExample.js,然后点击它。您会注意到 Firebug 提供了加载脚本的路径,如果您需要在您的环境中找到它,这非常方便。点击文件将其载入左窗格,如图 4-37 所示。

A978-1-4842-0544-0_4_Fig37_HTML.jpg

图 4-37。

SimpleExample.js file loaded in Firebug

您会注意到脚本文件的左边提供了行号。如果出现错误,这些非常方便,因为浏览器会让您知道错误发生在哪一行。您可以通过单击其中一个行号来设置断点。断点只是代码将停止运行的位置,以便您可以检查正在发生的事情。您可以设置多个断点;事实上,您可以在每行上设置一个。设置断点时,行号旁边会出现一个红点,如图 4-38 所示。

A978-1-4842-0544-0_4_Fig38_HTML.jpg

图 4-38。

Placing a breakpoint in the JavaScript file

一旦设置了断点,就可以重新加载页面,加载脚本时,一旦命中断点就会停止运行。如图 4-39 所示,当红点内有一个黄色箭头并且该线被高亮显示时,您可以看到这一点。

A978-1-4842-0544-0_4_Fig39_HTML.jpg

图 4-39。

Breakpoint hit while debugging SimpleExample.js in Firebug

既然脚本已经停止,您可以在 Watch 选项卡的右窗格中查看脚本正在使用的对象。例如,在这个success函数中,我们声明了一个名为data的变量,它是结果所在的位置。“观察”选项卡现在有了一个我们可以检查的data对象。点击data旁边的+图标,可以展开查看其属性。继续点击+图标直到看到结果,如图 4-40 所示。

A978-1-4842-0544-0_4_Fig40_HTML.jpg

图 4-40。

Data object that is sent back from the REST API

我们知道从我们的列表中返回的项目的数量,我们可以在results对象中看到这些。它们由它们在列表中的索引或位置来标记,并且索引总是从 0 开始。您可以进一步展开项目并查看它们的属性。单击 0 索引处项目旁边的+图标。您可以看到 SharePoint 返回了大量关于列表项的数据。这不仅仅适用于列表项——几乎任何你在 SharePoint 中请求的数据都会附带大量信息。向下滚动浏览项目中的所有属性,您会发现我们通过脚本显示的标题和描述属性,如图 4-41 所示。

A978-1-4842-0544-0_4_Fig41_HTML.jpg

图 4-41。

Expanding the first list item to inspect its properties

当您开发定制解决方案时,调试将证明对您非常有用,因为您可以检查所有返回的数据,以确保它正是您所需要的。它也非常方便,因为有时数据不在你想的地方。由于脚本在此处停止,您有几种方法可以再次启动它。按下键盘上的 F10 键会让脚本一次向前移动一行。这非常有帮助,因为您可以看到每一行执行时发生了什么。一些代码块将一起执行;例如,如果您使用 F10 来单步执行代码,$.each循环中的所有代码将作为一行。您可以很容易地在循环中放置另一个断点来停止它。

另一种选择是使用箭头图标,如图 4-42 所示。

A978-1-4842-0544-0_4_Fig42_HTML.jpg

图 4-42。

Continue to run the script by clicking the Play icon

这个图标只是告诉调试器继续并恢复处理脚本。如果没有其他断点,它将完全处理完脚本。按钮和文件位置在不同的开发工具之间会有很大的不同。你可以在图 4-434-44 中看到 Chrome 和 Internet Explorer 开发者工具。

A978-1-4842-0544-0_4_Fig44_HTML.jpg

图 4-44。

Developer tools in Internet Explorer 11

A978-1-4842-0544-0_4_Fig43_HTML.jpg

图 4-43。

Developer tools in Chrome

无论您使用哪种浏览器,或者开发人员工具看起来有多奇怪,请放心,它们都执行相同的功能。您可以检查 HTML,检查和更改 CSS,最重要的是,调试您的 JavaScript。随着您沿着使用 HTML 和 JavaScript 定制解决方案的道路前进,您会发现这些工具一如既往地重要。

摘要

在本章中,您了解了使用 HTML 和 JavaScript 构建定制解决方案的 Etherson 方法。我们讲述了各种组件,您看到了如何配置每个组件,并了解了它们如何作为一个单元一起工作。您构建了几个示例解决方案,并看到了在上传新文件后如何轻松地恢复代码。在您阅读本书的过程中,我们将继续在许多例子中使用这种方法,您将学习如何使用 CSS 扩展它。

在下一章,我们将探索使用 JSLink 来设计和增强列表视图 Web 部件。JSLink 是一种令人兴奋的新方法,可以为现成的 SharePoint 带来更多功能。它还可以与 JavaScript 结合,创建非常独特的解决方案来满足您的业务需求。