使用-HTML-和-JavaScript-为-SharePoint-2013-定制解决方案-二-

89 阅读54分钟

使用 HTML 和 JavaScript 为 SharePoint 2013 定制解决方案(二)

原文:Custom SharePoint solutions with HTML and JavaScript for SharePoint 2013

协议:CC BY-NC-SA 4.0

六、搜索 Web 部件的内容和显示模板

自从 SharePoint 出现以来,搜索一直在它的使用中扮演着重要的角色。无论是网站搜索、企业搜索还是自定义解决方案,SharePoint 的主要优势之一就是能够轻松找到所需内容。在 SharePoint 中简化搜索的方法之一是通过内容搜索 Web 部件。这可以很容易地放在页面上,并配置为向用户返回特定的结果。这是一个久经考验的 web 部件,已经存在很长时间了。在最新版本的 SharePoint 中,内容搜索 Web 部件利用了结果源和显示模板形式的新功能。

结果源允许您创建特定的搜索标准,以快速定位您正在寻找的内容。显示模板允许您根据您的业务需求设计和呈现这些搜索结果。这项新功能为开发人员在 SharePoint 中创建丰富的自定义解决方案提供了另一种途径。在这一章中,我们将看看这些领域,并创建一些自定义搜索解决方案。

添加文档

在开始使用 SharePoint 中的搜索功能构建解决方案之前,您需要实际搜索一些文档。如果您正在使用现有的 SharePoint 环境,您可能已经有了一些要搜索的文档。如果您已经为这本书设置了环境,您需要上传一些文档来执行一些搜索。在本例中,您可以搜索各种文档类型,包括 Word、Excel 和 PDF。图 6-1 显示了文档库中的一些样本文件。

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

图 6-1。

Excel, PDF, and Word documents in the Documents library Note

本例中使用的文档可以从一个网站下载。访问 Apress ( www.apress.com )并搜索这本书的书名来定位文档和源代码。

我使用了开箱即用的“文档”文档库,它是在我创建名为 Apress 的团队站点时创建的。无论您将文档存储在哪里,这里的主要要点是将一些文件上传到 SharePoint,以便您可以搜索它们。现在,一些文件已经上传并将最终被编入索引,您可以创建一个定制的结果源来方便搜索。

结果来源

在 SharePoint 2010 中,您有了自定义搜索范围的概念。它们允许您将搜索结果限制为特定内容,从而为您的最终用户提供更有针对性的搜索,而无需他们知道如何设计复杂的搜索查询。在 SharePoint 2013 中,您可以使用自定义结果源完成完全相同的事情。

在 SharePoint 2013 中执行搜索时,系统会将查询与结果源进行匹配以提供结果。结果源是指定以下内容的定义:

  • 协议——这可以是本地搜索服务索引、远程 SharePoint 安装、Exchange,甚至是另一个使用 OpenSearch 协议的搜索引擎。
  • 源 URL -如果您使用的是本地 SharePoint 以外的协议,您需要为返回搜索结果的服务提供一个 URL。
  • 类型-使用本地或远程 SharePoint 时,您可以指定 SharePoint 搜索或人员搜索。
  • 查询转换——使用查询转换,您可以使用 KQL 属性限制来缩小给定搜索的结果范围。
  • 凭据-您可以指定用于搜索的凭据。

SharePoint 附带了许多预配置的结果源供您使用,包括对话、文档和图片等。还可以在整个 SharePoint 中的不同级别创建自定义结果源,创建结果源的位置决定了您需要的权限级别。下面列出了可以创建结果源的级别以及创建结果源时所需的权限:

  • 网站集-您必须是网站集管理员,并且网站集中的任何网站都可以使用结果源。
  • 站点-您必须是该站点所有者组的成员,并且结果源只能由该站点使用。

您还可以在搜索服务应用级别或 SharePoint 管理中心为 Office 365 指定结果源,结果源可用于任何使用搜索服务应用的网站集。本书不会涉及这一层,但是,在这一层创建结果源的步骤也是完全相同的。

创建自定义结果源时,您需要决定的第一件事是创建它的级别。这取决于您打算如何使用源代码;例如,如果要突出显示特定站点中的项目,那么站点级别就有意义。但是,如果您想要一个更全面的结果源,您可能希望在网站集级别创建它。两者的步骤完全相同。如果您计划在网站集或网站级别创建新的结果源,只需导航到“网站设置”页面,选择“网站级别”的“搜索”标题下的“结果源”,或“网站集级别”的“网站集管理”标题下的“搜索结果源”。图 6-2 显示了网站集的网站设置页面。

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

图 6-2。

Accessing Result Sources from the Site Collection site settings page

正如您在网站集级别看到的,您可以为整个网站集创建结果源,也可以只为根级别的网站创建结果源。对于这个例子,我们将导航到其他代码样本所在的 Apress 子站点,并仅为这个站点创建一个新的结果源,如图 6-3 所示。

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

图 6-3。

Accessing Result Sources from the Site’s site settings page

单击“结果源”链接会将您带到“管理结果源”页面。此页面显示所有已设置的当前结果来源。它还包括 SharePoint 附带的所有现成的结果源。您不能更改任何现成的结果源;但是,您可以查看它们的设置。要开始创建自定义结果源,请单击页面顶部的新结果源链接,如图 6-4 所示。

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

图 6-4。

Manage Result Sources page in site settings

一旦进入 Add Result Source 页面,首先需要提供名称和描述。描述是可选的,但是您应该为其他用户提供一个描述。图 6-5 显示了新结果源所需的初始属性。

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

图 6-5。

Providing a name and description for the new result source

在本例中,您将创建一个结果源,该结果源将只返回网站文档库中的 PDF 文档。为此,我们将提供标题 Custom PDF Source 和适当的描述,以便用户确切地知道使用这个结果源时会发生什么。接下来,您需要提供一个协议和类型;在这种情况下,协议将是本地 SharePoint,类型将是 SharePoint 搜索结果,如图 6-6 所示。根据您的需要,您可能需要选择不同的协议和类型,并提供附加信息。在这种情况下,页面将更新以显示所选选项所需的附加字段。

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

图 6-6。

Protocol and Type options for the new result source

接下来,您需要提供一个查询转换,它将实际限制搜索结果。这是使用关键字查询语言完成的,关键字查询语言是一组搜索选项、属性限制和操作符。查询转换将始终以标记{searchTerms}开始;这将被替换为用户输入的任何搜索词。之后,您可以提供任何有效的属性限制和/或操作符。我们稍后将对此进行更深入的探讨。现在,您可以在文本框中看到{searchTerms}标记,以及启动查询生成器按钮,如图 6-7 所示。

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

图 6-7。

Query Transform options and the Launch Query Builder option

最后,您可以指定用于该结果源的凭据。您可以指定默认身份验证,以便在执行搜索时使用用户身份验证。这通常是期望的结果。认证类型如图 6-8 所示。

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

图 6-8。

Credentials Information for the result source

单击保存创建新的结果源。您将返回到管理结果源页面,其中将列出自定义结果源,如图 6-9 所示。新的结果源列在页面顶部的标题“为此网站定义”下。

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

图 6-9。

The new result source in the Manage Result Sources page

由于我们没有在查询转换部分提供任何细节,这个新的结果源将简单地接受用户的输入并执行搜索。我们绝对不需要创造一个新的结果来达到那个结果。让我们更新它,使它只从 Documents 文件夹返回 pdf。打开结果源快捷菜单,点击编辑,如图 6-10 所示。

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

图 6-10。

Editing the result source we just created

编辑结果源会将您带到“编辑结果源”页面,您将看到刚才输入的所有先前设置。向下滚动到查询转换部分,并单击启动查询构建器按钮,如图 6-11 所示。

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

图 6-11。

Query Transform section with the Launch Query Builder button

将打开“构建查询模式”窗口,这将帮助您构建查询转换。通过访问提供的下拉列表,您可以在此窗口中使用许多现成的过滤器。您也可以在这里应用排序和测试您的查询。您也可以选择只输入您的查询,如图 6-12 所示。

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

图 6-12。

The Build Your Query modal window

查询是使用关键字查询语言(简称 KQL)在 SharePoint 中构建的。使用 KQL,您可以指定传递给 SharePoint 搜索服务的搜索词或属性限制。KQL 查询并不复杂,由以下一个或多个元素组成:

  • 自由文本关键字——可以是单词或短语,比如白皮书、事件、Bob Smith 等等。
  • 属性限制——这些可以是文件类型、作者、文件名等等。

属性限制顾名思义就是限制搜索结果。例如,您可以添加一个文件类型限制器,并通过使用FileType:docx只返回 Word 文件来只返回特定的文档类型。有许多可用的属性限制,使得 KQL 在你的搜索需求中非常健壮。

Note

关键字查询语言虽然易于实现,但具有非常丰富和深刻的语法。这对于精心设计完全满足您需求的查询来说是很棒的,但是对于本书来说这是一个太大的主题。我们将简单地描述一下你能完成的事情。有关 KQL、财产限制等详细信息,请访问 http://msdn.microsoft.com/en-us/library/office/ee558911(v=office.15).aspx

KQL 查询必须包含一个自由文本关键字,或者一个属性限制,或者两者的组合才有效。首先,我们将删除查询的{searchTerms}部分。我们不会使用它,因为我们的内容搜索 Web 部件将简单地返回结果,而不需要用户的任何交互。接下来,我们将使用path属性添加一个属性限制:

path:"``https://brandonatkinson.sharepoint.com/apress/Shared Documents

path属性指示查询,我们只需要来自指定路径及其下的任何内容的结果,包括文件夹、子网站等等。路径必须是完全限定的 URL,如果它包含任何空格,URL 必须用引号括起来。在我的环境中,我使用现成的文档文件夹,它实际上是共享文档文件夹。您始终可以通过在导航面板中单击文件夹的实际名称并在浏览器的地址栏中检查 URL 来仔细检查该文件夹的实际名称。将该属性限制放置在查询文本文本框中并点击测试查询按钮将产生如图 6-13 所示的结果。

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

图 6-13。

Path property restriction returning only files from the specific document library

属性限制将搜索结果限制在文档库中,只有七个文档被返回。我们现在可以使用FileType属性再次限制它:

FileType:pdf

该属性指示查询只返回扩展名为.pdf的文件。将此添加到查询中并单击测试查询按钮将进一步限制结果,如图 6-14 所示。

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

图 6-14。

FileType property restriction limiting results to only PDF files

现在只有两个文件被返回,因为我们在文档库中只有两个 PDF 文件。虽然这是一个非常简单的例子,但是它应该说明了 KQL 在构造查询时所提供的强大功能。由于只有两个属性限制,我们已经能够很好地限制搜索结果。您可以想象,如果您要求只显示位于特定站点的 Office 文件,不管它们在哪个文件夹中,您的 KQL 查询将类似于以下内容:

path:"``http://SERVER/SITE

正如您所看到的,您可以组合相同类型的属性限制器来制作您所需要的东西。KQL 非常灵活;找到符合您需求的搜索词和属性限制的正确组合应该没有问题。

既然我们已经按照我们想要的方式设置了查询,那么在 Build Your Query 窗口中单击 OK。然后在“编辑结果源”页面上单击保存。自定义结果源现在已经设置好,可以使用了。接下来,让我们在页面上放置一个内容搜索 Web 部件,并使用结果源。

内容搜索 Web 部件

内容搜索 Web 部件是 SharePoint 2013 的另一个新功能。当内容搜索 Web 部件放置在页面上时,它会在用户加载页面时自动发出搜索查询。根据 web 部件的配置方式,用户很可能甚至不知道正在进行搜索。这使得内容搜索 Web 部件成为创建基于搜索的自定义解决方案的强大方法。这是一个易于使用和配置的 web 部件,正如您在上一节中看到的,根据您的需要设置特定的搜索查询非常容易。

Note

内容搜索 Web 部件是搜索 Web 部件功能的一部分。这仅适用于 SharePoint Online E3 和 E4 计划,以及企业内部许可。如果没有这些功能,您会发现内容搜索 web 部件不可用于向页面添加新的 Web 部件。您可以在 http://technet.microsoft.com/en-us/library/sharepoint-online-service-description.aspx 找到有关 SharePoint Online 计划可用功能的更多信息。

首先,导航到放置本书的其他 web 部件的页面,然后从前面的章节中删除任何现有的 web 部件。在页面仍处于编辑模式的情况下,通过从功能区中选择“插入”选项卡来放置新的内容搜索 Web 部件。从类别部分选择内容汇总,然后选择内容搜索,如图 6-15 所示。

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

图 6-15。

Inserting the Content Search Web Part onto the page

单击“添加”将 web 部件放置在页面上。web 部件将立即显示搜索结果。内容搜索 Web 部件的默认搜索名为“最近更改的项目”,它只显示最近更改的项目列表。在这种情况下,列表由最近添加到文档库中的文档组成,如图 6-16 所示。

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

图 6-16。

The Content Search Web Part using the Recently Changed Items search

乍一看,这个 web 部件几乎正在做我们从一开始就想做的事情,即只显示 PDF 文档。事实上,这两个 PDF 文档显示在这个 web 部件只是运气。例如,根据您上传文档的顺序,您可能会在顶部看到两个 Word 文档。我们将更新 web 部件以使用我们在上一节中创建的自定义结果源,从而确保我们在结果中仅获得 PDF 文档。将内容搜索 Web 部件置于编辑模式,在属性折叠窗格中,单击更改查询按钮,如图 6-17 所示。

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

图 6-17。

Accessing the query settings of the Content Search Web Part

单击此按钮将打开“构建您的查询模式”窗口。在“基本”选项卡下,您会看到“选择查询”标题和“最近更改的项目(系统)”选项,如图 6-18 所示。

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

图 6-18。

The Build Your Query modal window with the “Recently changed items” result source selected

正如您在此窗口中所看到的,内容搜索 Web 部件有许多设置,而且这些设置只与搜索查询有关!可以对该 web 部件进行配置,以提供非常准确的结果,并且它能够满足各种各样的业务需求。现在,让我们将结果源更改为自定义 PDF 源。点击切换到高级模式窗口右上角的链接,如图 6-19 所示。

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

图 6-19。

Switch to Advanced Mode link in the Build Your Query modal window

单击此链接会弹出一个窗口,该窗口看起来很像您在构建自定义结果源时看到的构建查询窗口。您可以键入查询,使用关键字过滤器和属性过滤器,甚至可以在右窗格中看到搜索查询的预览。当我们创建自定义结果源时,所有这些设置都可用;但是,这里有一个新的下拉菜单,名为“选择查询”。打开它将显示一个结果源列表,您可以选择用于查询。打开下拉列表,选择自定义 PDF 源,如图 6-20 所示。

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

图 6-20。

Choosing the custom result source Custom PDF Source from the drop-down menu

从下拉列表中选择结果源后,单击模式窗口底部的“测试查询”按钮预览自定义结果源查询。如图 6-21 所示,它正在执行仅从 documents 文件夹返回 PDF 文档的适当搜索。

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

图 6-21。

The Custom PDF Source result source search shown in the preview window

在“构建查询模式”窗口中,单击“确定”。接下来,在内容搜索 Web 部件工具窗格中单击“确定”保存更改。保存页面。自定义结果源将被激活,仅显示 PDF 文档,如图 6-22 所示。

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

图 6-22。

Custom result source displaying only PDF documents

现在,我们已经创建了一个自定义结果源,并成功地将其应用于内容搜索 Web 部件。只有结果源指定的文档被返回并显示给用户。然而,显示效果并不令人满意。虽然内容是正确的,但看起来不太好。接下来,让我们探索显示模板,看看如何应用定制样式来匹配定制结果。

Note

内容搜索 Web 部件相当复杂。它有许多设置可以配置,以帮助您实现非常精确的结果为您的解决方案。有关这些设置的更多详细信息,请访问 https://support.office.com/en-us/article/Configure-a-Content-Search-Web-Part-in-SharePoint-0dc16de1-dbe4-462b-babb-bf8338c36c9a

显示模板

SharePoint 允许您完全控制搜索结果,包括它们在页面上的显示方式。这是通过显示模板实现的。您可以使用显示模板来设计您的搜索结果,无论您喜欢使用 HTML。您可以创建两种类型的显示模板:

  • 控件-这些模板处理搜索结果显示的整体结构,可以包括页眉和页脚之类的内容。此模板在每个 web 部件上只会呈现一次。
  • Item -这些模板处理每个搜索结果项的显示方式。该模板将为返回的每个搜索结果呈现一次。

您可以通过将内容搜索 Web 部件置于编辑模式来查看这些显示模板,并且在工具窗格中,您可以在属性折叠中找到显示模板标题,如图 6-23 所示。

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

图 6-23。

Control and Item display templates in the Content Search Web Part tool pane

有许多现成的显示模板可用,您可以通过单击每种类型的下拉列表来查看它们。例如,控制模板包括列表、分页列表和幻灯片。项目模板甚至有更多的选项可供选择。要开始创建新的显示模板,最简单的方法是从现有模板开始。若要查看所有当前的搜索显示模板,请导航到母版页样式库,该样式库位于“网站设置”和“网站设计者样式库”下。点击“母版页和页面布局”链接,如图 6-24 所示。

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

图 6-24。

The “Master pages and page layouts” link in Site Settings

进入母版页样式库后,您会发现它比以前版本的 SharePoint 多了很多。靠近顶部有一个名为显示模板的文件夹。通过打开此文件夹,您将看到对应于 SharePoint 中不同区域的多个文件夹;其中之一是内容 Web 部件,如图 6-25 所示。

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

图 6-25。

Content Web Parts folder inside the Display Templates folder

打开“内容 Web 部件”文件夹,查看 SharePoint 自带的所有可用显示模板。如图 6-26 所示,这里有不少。在页面顶部,您可以看到在内容搜索 Web 部件工具窗格中看到的控件模板。

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

图 6-26。

Out-of-the-box display templates in the Content Web Parts folder

每个显示模板都有一个与之相关联的 JavaScript 文件。在幕后,SharePoint 使用这个 JavaScript 文件来呈现显示模板。您不需要创建或修改该文件;当你上传一个新的显示模板到这个文件夹时,一个相应的 JavaScript 文件被创建,我们将在本章的后面看到。

Note

显示模板可以非常简单,也可以非常复杂。您可以很好地控制哪些属性可用以及内容如何布局,甚至可以向模板添加额外的 JavaScript。显示模板的总体主题非常庞大和复杂,无法在本章中完全涵盖。更多信息请访问 http://msdn.microsoft.com/en-us/library/office/jj945138%28v=office.15%29.aspx

为了开始构建新的显示模板,我们将下载另一个模板的副本,并将其用作基础。显示模板可能相当复杂,从头构建一个模板可能是一项艰苦的任务。使用一个现有的模板开始将大大减少创建一个新模板的时间。对于这个例子,我们将关注一个项目模板,并使用默认的“图片在左边,3 行在右边”模板。在内容 Web 部件文件夹中,该模板的标题为Item_Picture3Lines.html。在文件夹中勾选此模板,在功能区中点击下载副本,如图 6-27 所示。

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

图 6-27。

Downloading a copy of an existing display template

一旦下载了副本,就可以在 Visual Studio 中打开它。检查一下这份文件,你会发现它有点复杂。它有一个 HEAD 部分、一个 TITLE 和一个 BODY——正如您所期望的 HTML 文档一样——以及许多呈现代码。实际的渲染发生在身体里。您会注意到在主体内部有几个包含所有逻辑的 div。Visual Studio 中的文件如图 6-28 所示。

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

图 6-28。

Item_Picture3Lines.html file open in Visual Studio

让我们将这个文件按每个部分进行分解,以便了解正在发生的事情。首先,保存文件并将其命名为 Item_CustomPdf.html。这些标签没有什么特别的。TITLE 标记非常重要,因为在内容搜索 Web 部件中选择项目模板时,它将显示在下拉列表中。将标题更改为自定义 PDF 模板。

<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">

<head>

<title>Custom PDF Template</title>

下一节是名为 CustomDocumentProperties 的一节中的属性集合。这些属性向 SharePoint 提供有关显示模板的附加信息。其中一些是自动为您填充的,而其他的您将需要更新。以下是一些比较重要的例子:

  • ManagedPropertyMapping -该属性获取搜索使用的托管属性,并将它们映射到显示模板可以使用的值。
  • MasterPageDescription -该属性为显示模板提供友好的描述,并显示给用户。
  • TargetControlType -该属性指定显示模板使用的上下文;例如,内容 Web 部件。

ManagedPropertyMapping属性允许您在搜索中使用托管属性,并将它们映射到显示模板可以使用的值。它是一个逗号分隔的值列表,使用以下格式:

'property display name'{property name}:'managed property'

例如,在这个显示模板中的ManagedPropertyMapping中,您可以找到以下内容:'Link URL'{Link URL}:'Path'。这将托管属性Path映射到一个名为Link URL的变量。ManagedPropertyMapping映射了几个托管属性:

<mso:ManagedPropertyMapping msdt:dt="string">'Picture URL'{Picture URL}:'PublishingImage;PictureURL;PictureThumbnailURL','Link URL'{Link URL}:'Path','Line 1'{Line 1}:'Title','Line 2'{Line 2}:'Description','Line 3'{Line 3}:'','SecondaryFileExtension','ContentTypeId'</mso:ManagedPropertyMapping>

映射属性后,您可以使用以下 JavaScript 获取其值:

var linkURL = $getItemValue(ctx, "Link URL");

getItemValue()函数有两个参数。第一个称为ctx,代表当前上下文。你会注意到它没有被定义。正好可以用。你需要记住的是,你必须把它传入,它会一直在那里使用。第二个参数是用单引号括起来的属性显示名,用在ManagedPropertyMapping元素中。在本例中,Link URL是属性名。

我们要更新的另一个属性是MasterPageDescription属性,只是为了更新描述,以免混淆。

<mso:MasterPageDescription msdt:dt="string">This Item Display Template will display custom PDF results.</mso:MasterPageDescription>

紧跟在<body>标记之后,您会发现一个<script>部分:

<script>

$includeLanguageScript(this.url, "∼sitecollection/_catalogs/masterpage/Display Templates/Language Files/{Locale}/CustomStrings.js");

</script>

在这一部分,您可以添加自己的脚本或 CSS 引用。默认情况下,它包含一个对名为CustomStrings.js的文件的引用,该文件存在于所有显示模板中。您可以使用以下几行来添加额外的引用:

  • 位于同一站点的脚本:$includeScript(this.url, "∼site/Webparts/CustomScript.js");
  • 位于外部站点的脚本:$includeScript(this.url, " http://www.contoso.com/CustomScript.js ");
  • 位于同一站点的 CSS 文件:$includeCSS(this.url, "∼site/Webparts/CustomCSS.css");

紧接在<script>标签之后,您会发现一个<div>元素,它包含了将包含在显示模板中的所有 HTML 和代码。这个 DIV 的 ID 必须与显示模板文件的名称相匹配。例如,本例中的 DIV 如下所示:

<div id="Item_CustomPdf">

在 DIV 元素之后,您会看到注释块中的代码以<!--#_开始,以_#-->结束。在这个块中,您可以使用任何您喜欢的 JavaScript 代码,在这里您还可以获得任何托管属性的所有值。我们将保持这个显示模板的简单,只使用两个托管属性,代码如下:

<!--#_

var linkURL = $getItemValue(ctx, "Link URL");

var line1 = $getItemValue(ctx, "Line 1");

_#-->

如您所见,我们简单地声明了两个变量来保存在ManagedPropertyMapping中定义的托管属性的值。我们将在 HTML 代码中使用这两个变量。我们将用下面的代码保持 HTML 的简单:

<div style="border:solid 1px Silver;padding:10px;margin-bottom:20px;">

<strong>_#= line1 =#_</strong>

<br />

<a href="_#= linkURL =#_">

_#= linkURL =#_

</a>

</div>

在这段代码中,我们简单地用一个 DIV 包装所有内容。我们通过内联 CSS 应用了一个简单的边框和填充。接下来,我们将使用下面的语法: _#= line1 =#_显示line1变量。通过使用以下语法,可以在显示模板中使用 JavaScript 变量。接下来,我们将使用一个<a>元素显示 PDF 文件的链接。完整的文件如图 6-29 所示。

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

图 6-29。

Display template in Visual Studio

导航回母版页样式库中的内容 Web 部件文件夹,并从功能区将Item_CustomPdf.html文件上载到库中。文件上传后,会出现一个模态窗口提示您,您可以在其中设置文件的属性,如图 6-30 所示。

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

图 6-30。

Properties dialog for the display template

该对话框具有您在显示模板的 HTML 文件中看到的许多属性。文件中的所有属性都将被提取并填充到此窗口中。因此,您几乎可以保持所有属性不变,然后单击 Save。你会看到显示模板已经上传到库中,如图 6-31 所示。

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

图 6-31。

The newly uploaded display template and generated JavaScript file

您还会看到已经创建了一个同名的配套 JavaScript 文件。SharePoint 根据您上载的 HTML 文件生成此文件。这是它在呈现内容时使用的内容。你不需要担心这个文件,也不应该试图修改它。如果您需要进行更改,只需更改 HTML 文件并再次上传即可。每次您上传 HTML 的新副本时,都会生成一个新的 JavaScript 文件。

导航回包含内容搜索 web 部件的页面,并将该 Web 部件置于编辑模式。如果您单击显示模板部分中的项目下拉菜单,您将看到自定义 PDF 模板作为一个选项,如图 6-32 所示。选择此选项,单击确定,然后保存页面。

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

图 6-32。

The new display template is available for use

页面重新加载,呈现新的显示模板,如图 6-33 所示。

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

图 6-33。

The new display template being used to render the Content Search Web Part

这个例子是你能得到的最基本的例子,但是希望它展示了显示模板和搜索 web 部件的简单和强大。使用这些模板,您可以构建利用托管属性、JavaScript 和 CSS 的自定义搜索解决方案。创建丰富体验所需的所有工具都已准备就绪。

Note

花些时间下载并探索 SharePoint 附带的现成显示模板。只需浏览这些文件并查看每个文件中使用的代码,就可以找到许多有用的信息。

摘要

在本章中,我们探讨了如何使用内容搜索 Web 部件、自定义结果源和自定义显示模板来构建自定义搜索解决方案。您了解了结果源,并了解了如何构建新的源并将其用于内容搜索 Web 部件。我们很快研究了显示模板,并创建了一个简单的例子来说明如何应用自定义渲染。搜索将永远在 SharePoint 中发挥重要作用,现在您有了一些工具来为您的业务需求构建自定义搜索解决方案。

在下一章中,我们将继续探索 SharePoint 在设计定制解决方案时所提供的功能。我们将研究一些内置的 JavaScript 功能,这些功能在编写代码时唾手可得。我们已经看到了一些这种功能,我们将更深入地探究什么是可能的。

七、使用 SharePoint 的内置 JavaScript 函数和属性

当使用 JavaScript 构建定制解决方案时,经常需要其他库的帮助来完成您的工作。我们已经看到了 jQuery 库的强大功能,以及它如何帮助我们在页面上定位 HTML 元素、更新它们的值,甚至使用 AJAX 调用数据。使用 SharePoint 时,您经常需要构建 URL、向用户显示通知等。幸运的是,微软提供了大量的 JavaScript 来帮助你完成这些任务。我不是简单地谈论 JavaScript 对象模型或 REST API。在这一章中,我们将探索一些内置的 JavaScript 函数和属性,它们可以很容易地帮助你构建你的定制解决方案。

探索 JavaScript

SharePoint 附带了一长串内置的 JavaScript 方法和属性,您可以在代码中使用它们。事实上,这份清单太长了,一旦你开始钻研,它似乎会让人不知所措。然而,在您的日常编码工作中,您将很快习惯其中的一些,并且当需要时,您可以放心地知道有更多的帮助。让我们首先使用 Internet Explorer 11 的开发工具来探索一些文件。正如本书前面提到的,每种浏览器都有自己的一套开发工具,每种工具都略有不同。你完全可以在每一个中执行相同的任务,但是一旦你开始在 JavaScript 控制台中键入,IE11(和 Chrome)会显示一个可用功能的便捷列表,如图 7-1 所示。

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

图 7-1。

Developer tools in IE11. Typing an underscore in the console window will display a list of available JavaScript functions

通过按键盘上的 F12 打开 IE11 中的开发工具。您也可以通过浏览器中的设置按钮来访问它们。单击控制台选项卡,并在底部的文本框中键入下划线。将打开一个列表,显示所有以下划线开头的 JavaScript 函数。您可以使用箭头键在列表中上下移动。

花几分钟时间浏览你在这里看到的一切。它应该给你一个很好的指示,说明在 SharePoint 中使用 JavaScript 的可能性。您已经看到了其中一些功能的运行;例如,当使用 JSLink 时,我们利用了SPClientTemplates功能来覆盖 web 部件呈现。

Note

可供您使用的 JavaScript 方法和属性非常广泛。以至于没有办法在一个单独的章节中恰当地涵盖它;这需要一整本书。我们将查看一些功能,并在示例代码中使用它们。你应该花些时间充分探索开发者工具中的功能,并使用 Google 或 Bing 追踪更多信息。

_spBodyOnLoadFunctions

_spBodyOnLoadFunctions是一个数组,它保存了一组 JavaScript 函数,这些函数应该在页面加载时被触发。我们在第五章中看到过,当我们需要连接一个函数来触发页面加载时。该数组包含一个名为push的方法,您可以在其中传入应该被触发的函数的名称:

_spBodyOnLoadFunctions.push(<FUNCTION_NAME>);

当您无法访问 jQuery Document.ready()函数时,这是一个非常有用的函数。还有一个等价的函数叫做ExecuteOrDelayUntilBodyLoaded,它执行相同的任务,甚至有相同的签名:

ExecuteOrDelayUntilBodyLoaded(<FUNCTION_NAME>);

_spPageContextInfo

在编写任何类型的代码时,无论是 JavaScript 还是 C#之类的,总会有需要了解页面、位置或其他环境变量的时候。_spPageContextInfo对象可以轻松地提供大量有用的信息。在本书的大多数例子中,它被用来提供位置信息,以便构建请求数据的 URL。起初,这似乎不是非常重要的信息,但是当进行 REST API 调用或者通过 JavaScript 对象模型定位另一个站点时,它变得极其重要。

Note

在 Firebug 或开发工具中,可以很容易地访问_spPageContextInfo对象的所有属性。只需打开 JavaScript 控制台窗口,在每个窗口中键入内容,就可以看到您的环境的结果。

_ sppagecontext info . site absolute URL

此属性提供用户所在的当前网站集的绝对 URL。绝对 URL 是完全限定的 URL,它包含协议(http://https://)和域名( www. yoursite .com )。由于 SharePoint 可以利用备用访问映射,从而允许您对相同的内容使用不同的域,因此该功能提供了一种非常有用的方法来构建 URL,而不必担心用户从哪里访问页面。

由于这是网站集的路径,因此生成的 URL 可能类似于以下内容:

  • http://www.<DOMAIN>.com
  • http://www.<DOMAIN>.com/sites/<SITE_NAME >

_ sppagecontext info . site server relative URL

此属性为用户所在的当前网站集提供相对于服务器的 URL。相对 URL 只是从 URL 中省略了协议和域。这是一个方便的工具,因为很多时候你需要网站集的相对 URL。如前所述,由于 SharePoint 内容能够在许多不同的域上被访问,因此以相对 URL 为目标允许您跨多个域发布相同的代码,而不用担心代码将在哪里运行。

例如,如果您要在根站点集合中调用该属性,那么产生的 URL 将只是/

_ sppagecontextinfo . webabsoluteurl

此属性提供用户所在的当前网站的绝对 URL。这是包括协议和域的完全限定的 URL。URL 生成的代码如下所示:

  • http://www.<DOMAIN>.com
  • http://www.<DOMAIN>.com/<SUBSITE >
  • http://www.<DOMAIN>.com/sites/<SITE_COLLECTION>/<SUBSITE >

_ sppagecontextinfo 服务器相对关系

此属性为用户所在的当前网站提供相对于服务器的 URL。与相对于站点的 URL 一样,它从 URL 中省略了协议和域。URL 生成的代码如下所示:

  • /
  • /<SUBSITE>
  • /sites/<SITE_COLLECTION>/<SUBSITE>

ExecuteOrDelayUntilScriptLoaded

这个函数允许您指定一个 JavaScript 函数延迟,直到另一个脚本被完全加载。本质上,我们是在告诉 SharePoint:“我想运行这个特定的函数,但是我需要等到这个脚本被加载。”它有以下签名:

ExecuteOrDelayUntilScriptLoaded(<FUNCTION_NAME>, <SCRIPT_FILE>);

SharePoint 首先检查是否加载了指定的 JavaScript 文件;如果是,它会立即执行指定的函数。如果文件没有被加载,它将函数调用放入一个队列中,稍后再执行。我们将在下一章使用 JavaScript 对象模型查询用户数据时用到它:

$(function () {

ExecuteOrDelayUntilScriptLoaded(getUserProfileProperties, "sp.userprofiles.js");

});

function getUserProfileProperties() {

var clientContext = new SP.ClientContext();

...

正如您在这个代码片段中看到的,我们有一个 jQuery Document.ready()函数,我们在其中放置了ExecuteOrDelayUntilScriptLoaded函数。我们传入函数getUserProfileProperties和 JavaScript 文件sp.userprofiles.js。我们需要在这里实现这个函数,因为函数中包含的代码只有在加载了sp.userprofiles.js文件的情况下才能运行。SharePoint 提供了一种确保代码功能的简单方法!

Note

ExecuteOrDelayUntilScriptLoaded功能是 SharePoint 2010 的延续,它位于SP.SOD对象下。SharePoint 2013 中存在较新版本无法正常工作的情况,通常是在发布门户页面上。如果您发现此功能不起作用,您可以恢复到 2010 年的实现。更多信息请访问 http://msdn.microsoft.com/en-us/library/office/ff408081%28v=office.14%29.aspx

物种 UI .通知

SP.UI.Notify对象提供了多种方式来通知用户有事情发生。此功能提供了一种利用现成 SharePoint 通知的方式,并允许您的自定义解决方案无缝融入环境。虽然本书中的示例没有利用这种通知框架,但是可以很容易地对它们进行重构,以便在发生创建或删除操作时包含通知。如果可能的话,通知用户事件的发生总是一个好的做法。

SP(存储处理器)。ui . notify . showloadingnotification

SP.UI.Notify.showLoadingNotification功能是显示熟悉的“正在处理中...”的一种快速简单的方式通知。如果你使用 SharePoint 有一段时间了,你肯定会看到这些信息中的一条,它会从屏幕的右侧弹出。它包括一个“旋转器”图标,如图 7-2 所示。

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

图 7-2。

Loading notification launched via Firebug

您可以随时在代码中使用以下代码行启动此通知:

SP.UI.Notify.showLoadingNotification();

事实上,您也可以启动 Firebug 或开发人员工具,并在浏览器中直接调用它。图 7-2 显示了从控制台通过 Firebug 触发的通知。

这是一种快速便捷的方式,通过您的代码通知用户有事情发生。虽然这种一般的通知在某些情况下肯定是足够的,但是您可能需要提供更多关于正在发生的事情的解释。为此,您可以使用SP.UI.Notify.addNotification方法。

物种 UI.Notify.addNotification

与前面的函数非常相似,SP.UI.Notify.addNotification用于在同一位置向用户显示通知,但带有自定义消息。当您需要通知用户一个动作正在发生,但需要比简单的“正在进行中...”更具描述性时,这是非常完美的消息。图 7-3 显示了正在显示的自定义信息。

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

图 7-3。

A custom message being displayed to notify the user

您可以使用以下命令行启动此通知:

SP.UI.Notify.addNotification("Your Custom Message");

如您所见,通过 JavaScript 添加自定义通知再简单不过了。您显示的消息没有最大长度限制。然而,随着消息变长,它最终会到达屏幕的另一侧,文本开始换行。这可能并不总是正确的布局,所以最好保持你的信息简短。图 7-4 显示了一条更长的信息。

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

图 7-4。

A longer message can be displayed via a notification

通知只会在页面上停留大约 6 秒钟。如果您只需要通知用户发生了一个动作,但不需要等待响应,这就很好。然而,有时候你需要开始一个行动,然后等待一个结果。在这种情况下,你可能需要你的通知多留一会儿。您可以使用以下行包含一个布尔值来指示通知应该保留:

SP.UI.Notify.addNotification("Your Custom Message", true);

通过使用前面的代码行,通知将一直存在,直到被手动关闭。您可以通过调用SP.UI.Notify.removeNotification函数,从addNotification函数调用传入通知 ID 来实现这一点。当您调用addNotification函数时,您会得到刚刚创建的通知的 ID,如图 7-5 所示。

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

图 7-5。

The Notification ID that is returned when you create a new notification

如果我们在代码中使用它,该行将如下所示:

var notifyId = SP.UI.Notify.addNotification("Hello World", true);

当我们执行这一行时,notifyId变量现在有了新创建的通知的 ID。稍后,我们可以使用以下代码行来关闭通知:

SP.UI.Notify.removeNotification(notifyId);

SP.UI.Notify.removeNotification只是获取通知的 ID 并将其从屏幕上删除。当调用showLoadingNotification函数时,也可以使用布尔标志:

SP.UI.Notify.showLoadingNotification(true);

传入布尔值触发通知 ID 的相同返回,如图 7-6 所示。

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

图 7-6。

A Notification ID is returned when using the Boolean flag

这些函数提供了一种简单的方式,通过 JavaScript 通知用户正在发生什么。例如,如果您需要执行一个长时间运行的 AJAX 调用,您可以让用户知道这正在发生,这样他们就不会对您的 web 部件失去耐心。

摘要

微软已经走了很长一段路,不仅为开发人员提供了通过 JavaScript 访问数据的方法,还开发了核心的 SharePoint 功能。在这一章中,我们探索了一些内置的 JavaScript 函数和属性。我们看到了如何访问位置数据来更容易地为 REST API 调用和超链接构建 URL。我们看到了如何将函数调用加载到 SharePoint 内的 body onload 事件中,以及如何确保在执行代码之前功能对代码可用。最后,我们看了一些不同的方法来通知你的用户你的代码正在做什么来提供更好的用户体验。

八、使用 JavaScript 对象模型

到目前为止,已经向您介绍了使用 HTML 和 JavaScript 在 SharePoint 中创建自定义解决方案的几种不同方法。在这一章中,我们将继续探索使用 Etherson 方法来创建定制的 web 部件以及 JavaScript 对象模型。在第二章中,我们简要地看了一下 JavaScript 对象模型,或 JSOM。在这一章中,我们将了解如何使用 JSOM 处理列表、库、文件、网站和社交数据。将向您介绍使用 SharePoint 数据的各种方法,并开始全面了解这项技术的威力。

JSOM 有能力为您的发展需求提供广泛的选择。您可以创建新列表和网站;你可以读取文件,与社交数据互动。到本章结束时,你将对如何编写 JSOM 代码有一个坚实的掌握,并知道它能做什么。

Note

利用 JavaScript 对象模型的代码在登录用户的上下文中运行。这意味着代码只能执行用户权限级别允许的操作。例如,如果您有在网站集中创建新的子网站的代码,但登录的用户没有该权限,它将运行但会产生错误。在构建解决方案时请记住这一点,并确保不向用户展示他们无法利用的选项。

正在设置

在开始之前,我们需要在本书中一直使用的演示列表中添加一些额外的数据。添加一些额外的数据将允许我们查询更多的数据和应用过滤器。导航到演示列表,并添加更多具有不同状态的列表项。更新后的列表如图 8-1 所示。

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

图 8-1。

Demo List with more items added to it

现在我们在列表中有了一些额外的数据,让我们开始看看如何使用 JSOM 查询数据。本章中的例子将利用第四章中介绍的 Etherson 方法。导航到站点中的 Webparts 文件夹,新建一个名为 Chapter 8 的文件夹,如图 8-2 所示。

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

图 8-2。

Chapter 8 folder in the Webparts document library

本章中的每个例子都将遵循相同的模式。我们将查看在内容编辑器 Web 部件中呈现的 HTML 文件,用于检索和呈现数据的 JavaScript 文件,最后是结果。在这个过程中,我们将深入每个文件并解释发生了什么。

使用列表

SharePoint 中到处都是列表!作为用户,您将在 SharePoint 中与列表进行交互。下面的例子将演示通过代码与列表交互的各种方式。

获取列表数据

在这个例子中,我们将简单地检索一些列表数据来显示给用户。

超文本标记语言

在 Visual Studio 中创建新的 HTML 文件,并将其命名为 JSOMGetListData.html。本例的 HTML 非常简单,仅包含以下几行:

<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.js"></script>

<script type="text/javascript" src="/apress/webparts/chapter 8/JSOMGetListData.js"></script>

<div id="divGetListData"></div>

首先,您会注意到我们必须加载两个 SharePoint JavaScript 文件:sp.runtime.jssp.js。这两个文件非常重要,因为它们提供了正确运行 JSOM 代码所需的必要代码。在 SharePoint 2010 中,所有需要的 JavaScript 总是加载在每个页面上。这使得 JavaScript 开发变得更加容易,因为您不必担心核心 SharePoint 脚本是否被加载。在 SharePoint 2013 中,只加载页面所需的基本代码。这有助于 SharePoint 更快地加载页面;但这也意味着,如果你需要一个特定的库,你需要确保它是加载的。在我们的例子中,我们需要这两个文件。

接下来,我们加载名为JSOMGetListData的自定义 JavaScript 文件。该文件包含将数据加载到页面上的 DIV 的所有代码,该页面的 ID 为divGetListData。总而言之,这一页没有多少内容。

Java Script 语言

在 Visual Studio 中创建一个新的 JavaScript 文件,并将其命名为 JSOMGetListData.js。相比之下,该 JavaScript 文件更复杂,由以下几行组成:

$(function () {

getListData();

});

function getListData() {

var clientContext = new SP.ClientContext();

var oWebsite = clientContext.get_web();

this.collList = oWebsite.get_lists();

clientContext.load(collList);

clientContext.executeQueryAsync(

Function.createDelegate(this, this.onQuerySucceeded),

Function.createDelegate(this, this.onQueryFailed)

);

}

function onQuerySucceeded() {

var listInfo = '';

var listEnumerator = collList.getEnumerator();

while (listEnumerator.moveNext()) {

var oList = listEnumerator.get_current();

listInfo += 'Title: ' + oList.get_title() + ' - Created: ' +

oList.get_created().toString() + '<br />';

}

$("#divGetListData").html(listInfo);

}

function onQueryFailed(sender, args) {

alert('Request failed. ' + args.get_message() +

'\n' + args.get_stackTrace());

}

本书中的大多数 JSOM 例子都遵循与这个例子相同的模式。让我们深入到每一行的细节,以充分了解发生了什么。该脚本以一个 jQuery Document.ready方法开始,该方法简单地调用一个名为getListData的自定义函数,该函数进行 JSOM 调用,并且是主要代码所在的位置。

首先,我们创建一个名为clientContext的新变量,并使用以下代码行设置它:

var clientContext = new SP.ClientContext();

客户端上下文是一个 SharePoint 对象,它实际上是所有 JSOM 调用的入口点。它保存了大量关于当前站点、用户、web 等的上下文信息。在这个例子中,我们只是要求返回上下文,而不传递任何参数。这将自动返回当前站点的上下文。您也可以通过传入一个 URL 来询问其他站点的上下文;比如,SP.ClientContext(' http://www.site.com ')

接下来,我们创建另一个名为oWebsite的变量,并使用以下代码行设置它:

var oWebsite = clientContext.get_web();

这将为我们提供用户执行代码的站点集合中的当前站点或网站。我们需要这个网站来获取所有的列表。接下来,我们使用下面的代码行创建另一个名为collList的变量:

this.collList = oWebsite.get_lists();

该变量由来自oWebsite变量的所有列表填充。collList变量的声明与其他变量略有不同,因为这里没有var关键字,而是this。这样做的原因是,this关键字将使这个变量成为全局变量,以便以后处理数据所需的函数可以访问它。

当您第一次开始使用 JSOM 时,下一行通常会让您感到头疼:

clientContext.load(collList);

这一行将查询“加载”到客户端上下文中,以发送到 SharePoint。这意味着此时您实际上还没有向 SharePoint 发送任何数据请求。在大多数 JavaScript 开发中,您可能会认为像this.collList = oWebsite.get_lists();这样的行会立即返回所有列表,您可以开始使用它们了。在 JSOM,情况并非如此。您必须加载您想要发出的任何请求,然后使用下面的行提交它们:

clientContext.executeQueryAsync(

Function.createDelegate(this, this.onQuerySucceeded),

Function.createDelegate(this, this.onQueryFailed)

);

直到调用executeQueryAsync函数,对 SharePoint 的请求才真正发生。在使用 JSOM 时,理解这一点非常重要,这也是很多开发人员第一次起步时会犯的错误。在提交请求之前必须加载所有请求的原因是一个称为批处理的特性。基本上,SharePoint 允许您加载多个数据请求,然后只进行一次执行调用来获取您需要的所有数据。这使得实际处理 JSOM 调用的服务器性能更好。本书中没有一个例子真正利用了批处理,但这是一个需要了解的重要概念。

executeQueryAsync方法允许您指定一个success函数和一个failure函数,它们在 SharePoint 返回查询结果后被调用。这些是使用Function.createDelegate方法声明的,如前所示。一旦指定了这些,就需要创建函数来实际处理结果。

function onQuerySucceeded() {

var listInfo = '';

var listEnumerator = collList.getEnumerator();

while (listEnumerator.moveNext()) {

var oList = listEnumerator.get_current();

listInfo += 'Title: ' + oList.get_title() + ' - Created: ' +

oList.get_created().toString() + '<br />';

}

$("#divGetListData").html(listInfo);

}

这个函数以一个名为listInfo的新变量开始,这个变量将用于保存查询的所有结果,然后将它们显示在页面上。接下来,我们使用collList.getEnumerator()方法从collList变量中获取一个枚举器,并将其放入一个名为listEnumerator的变量中。我们需要遍历返回的所有结果,枚举器允许我们这样做。使用while循环,我们遍历使用listEnumerator.get_current()方法返回的每个项目。在每个循环中,我们从当前项目中获取标题和创建日期。我们包含更多的 HTML,并使用+=将内容添加到listInfo变量中。这允许我们不断向listInfo变量添加内容,而不是每次都覆盖它。

最后,我们使用$("#divGetListData").html(listInfo);listInfo变量的内容输出到 HTML 页面中的 DIV。

结果

将内容编辑器 Web 部件的内容链接属性设置为 HTML 文件,并保存页面。结果将显示当前站点的所有列表,如图 8-3 所示。

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

图 8-3。

Get List Data results in the Content Editor Web Part

创建新列表

在本例中,我们将创建一个新列表。我们不会做任何花哨的事情,只是创建一个新的列表并设置它的标题。

超文本标记语言

在 Visual Studio 中创建新的 HTML 文件,并将其命名为 JSOMCreateList.html。这个示例的 HTML 比上一个示例稍微复杂一些,它由以下几行组成:

<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.js"></script>

<script type="text/javascript" src="/apress/webparts/chapter 8/JSOMCreateList.js"></script>

<div>

<strong>Enter a name for the list:</strong>

<input type="text" id="txtListName" />

<input type="button" id="btnSubmitListName" value="Submit" />

</div>

<div id="divCreateListResults"></div>

和以前一样,我们需要加载sp.runtime.jssp.js文件,以及对我们定制的 JavaScript 文件的引用。HTML 稍微复杂一点,页面上有几个元素。首先,一些简单的文本被包装在一个<strong>标签中,使其在页面上加粗。接下来,有一个文本类型的输入,它只是一个简单的文本框,供用户输入他们希望创建的列表的名称。有一个按钮供用户提交新的列表请求,最后还有一个 DIV,我们可以在其中输出列表创建的结果。每个元素都有一个 ID,所以我们可以很容易地用 jQuery 找到它。

Note

为了通过 JSOM 创建新列表,执行代码的用户必须至少拥有 SharePoint 中的“管理列表”权限。无论权限级别如何,都将呈现该页面;但是,如果用户没有足够的权限,SharePoint 将引发错误。

Java Script 语言

在 Visual Studio 中创建新的 JavaScript 文件,并将其命名为 JSOMCreateList.js。相比之下,JavaScript 文件更复杂,它由以下几行组成:

$(function () {

bindButtonClick();

});

function bindButtonClick() {

$("#btnSubmitListName").on("click", function () {

var listName = $("#txtListName").val();

createList(listName);

});

}

function createList(listName) {

var clientContext = new SP.ClientContext();

var oWebsite = clientContext.get_web();

var listCreationInfo = new SP.ListCreationInformation();

listCreationInfo.set_title(listName);

listCreationInfo.set_templateType(SP.ListTemplateType.genericList);

this.oList = oWebsite.get_lists().add(listCreationInfo);

clientContext.load(oList);

clientContext.executeQueryAsync(

Function.createDelegate(this, this.onQuerySucceeded),

Function.createDelegate(this, this.onQueryFailed)

);

}

function onQuerySucceeded() {

var results = oList.get_title() + ' successfully created!';

$("#divCreateListResults").html(results);

}

function onQueryFailed(sender, args) {

alert('Request failed. ' + args.get_message() +

'\n' + args.get_stackTrace());

}

在这个例子中,我们不需要在页面加载上触发任何动作;然而,我们确实需要在页面加载时连接一个按钮点击事件。在Document.ready函数中,我们触发了bindButtonClick函数。在这个函数中,我们使用 jQuery on操作符在 HTML 中的btnSubmitListName按钮上连接一个点击事件。当用户点击按钮时,我们从页面上的文本框中获取文本,并使用以下代码行将其传递给createList()函数:

function bindButtonClick() {

$("#btnSubmitListName").on("click", function () {

var listName = $("#txtListName").val();

createList(listName);

});

}

createList()函数接受一个名为listName的变量,它是用户在页面上输入的文本。接下来,我们获取对当前客户端上下文的引用,并获取当前 web。然后,我们使用以下代码创建列表:

var listCreationInfo = new SP.ListCreationInformation();

listCreationInfo.set_title(listName);

listCreationInfo.set_templateType(SP.ListTemplateType.genericList);

this.oList = oWebsite.get_lists().add(listCreationInfo);

clientContext.load(oList);

为了创建一个新的列表,我们使用了一个SP.ListCreationInformation()对象。我们可以使用下面的代码实例化一个新的ListCreationInformation对象:

var listCreationInfo = new SP.ListCreationInformation();

这一行所做的就是创建一个新对象,并给它分配一个名为listCreationInfo的新变量。接下来,我们使用以下代码行设置标题和模板:

listCreationInfo.set_title(listName);

listCreationInfo.set_templateType(SP.ListTemplateType.genericList);

set_title方法接受传递给函数的listNameset_templateType方法接受一个内置值SP.ListTemplateType,在本例中,我们传入的是genericList。如果使用 SharePoint UI 在浏览器中创建列表,这里的可用值将是您期望看到的任何值,例如:公告、日历、任务等等。接下来,我们使用以下代码行将列表添加到 web:

this.oList = oWebsite.get_lists().add(listCreationInfo);

clientContext.load(oList);

就像前面的例子一样,在我们将列表添加到站点之后,我们将列表“加载”到客户端上下文中。最后,我们调用executeQueryAsync函数,该函数实际上会调用 SharePoint 来创建列表。调用完成后,我们使用以下函数处理结果:

function onQuerySucceeded() {

var results = oList.get_title() + ' successfully created!';

$("#divCreateListResults").html(results);

}

在这个函数中,使用oList.get_title()方法,我们可以获得刚刚创建的列表的标题。这是一个很好的检查,可以确保列表确实被创建了,因为我们从列表本身获得标题,而不是使用用户输入的文本。一旦我们有了列表标题,我们使用 jQuery 将成功消息添加到页面上的divCreateListResults DIV 中。

结果

将内容编辑器 Web 部件的内容链接属性设置为 HTML 文件,并保存页面。该页面现在将显示文本框和按钮,供用户输入新的列表名称。键入我的自定义列表,然后单击提交按钮。结果将显示成功信息,如图 8-4 所示。

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

图 8-4。

Create new list code after it has been run

因为这些都是使用 JavaScript 和 AJAX 完成的,所以列表会被创建,用户会得到预期的通知。但是,页面上的左侧导航将不会更新,因为页面尚未刷新。您完全可以更改这段代码,以便在成功时刷新页面,但是在本例中,我们只是在浏览器中刷新页面。图 8-5 显示了刷新后的页面,新列表显示在左侧导航中。

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

图 8-5。

The new list as displayed in the left navigation pane

删除列表

在本例中,我们将简单地删除我们在上一节中刚刚创建的列表。

超文本标记语言

在 Visual Studio 中创建新的 HTML 文件,并将其命名为 JSOMDeleteList.html。此示例的 HTML 与上一个示例几乎相同,它由以下几行组成:

<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.js"></script>

<script type="text/javascript" src="/apress/webparts/chapter 8/JSOMDeleteList.js"></script>

<div>

<strong>Enter the name of the list to delete:</strong>

<input type="text" id="txtListName" />

<input type="button" id="btnSubmitListName" value="Submit" />

</div>

<div id="divDeleteListResults"></div>

这里唯一的不同是,我们更新了页面上的文本,以表明这是将删除列表的 web 部件,并且我们将结果 DIV 的 ID 更改为divDeleteListResults

Java Script 语言

在 Visual Studio 中创建一个新的 JavaScript 文件,并将其命名为 JSOMDeleteList.js。

$(function () {

bindButtonClick();

});

function bindButtonClick() {

$("#btnSubmitListName").on("click", function () {

var listName = $("#txtListName").val();

deleteList(listName);

});

}

function deleteList(listName) {

var clientContext = new SP.ClientContext();

var oWebsite = clientContext.get_web();

this.oList = oWebsite.get_lists().getByTitle(listName);

oList.deleteObject();

clientContext.executeQueryAsync(

Function.createDelegate(this, this.onQuerySucceeded),

Function.createDelegate(this, this.onQueryFailed)

);

}

function onQuerySucceeded() {

$("#divDeleteListResults").html("List successfully deleted!");

}

function onQueryFailed(sender, args) {

alert('Request failed. ' + args.get_message() +

'\n' + args.get_stackTrace());

}

该脚本从熟悉的 jQuery Document.ready函数开始,它将按钮点击绑定到一个函数:

function bindButtonClick() {

$("#btnSubmitListName").on("click", function () {

var listName = $("#txtListName").val();

deleteList(listName);

});

}

这个函数与上一个例子几乎相同——除了删除列表的新函数名deleteList。这个函数更小也更切题,只有几行相关的代码:

this.oList = oWebsite.get_lists().getByTitle(listName);

oList.deleteObject();

在获得对客户端上下文和当前 web 的引用后,我们使用 web 对象上的getByTitle()方法来定位我们希望删除的列表,然后将它赋给一个名为oList的变量。接下来,我们调用oList.deleteObject()方法来实际执行删除。您会注意到,在客户端上下文对象上没有“load”方法。删除列表时,不需要执行此步骤。在deleteObject()行之后,您可以简单地调用executeQueryAsync()方法来执行删除操作。

结果

将内容编辑器 Web 部件的内容链接属性设置为 HTML 文件,并保存页面。该页面现在将显示文本框和按钮,供用户输入要删除的列表名称。键入我的自定义列表,然后单击提交按钮。结果将显示成功信息,如图 8-6 所示。

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

图 8-6。

Delete List code after it has successfully run

因为这些都是使用 JavaScript 和 AJAX 完成的,所以列表将被删除,用户将得到预期的通知。但是,页面上的左侧导航将不会更新,因为页面尚未刷新。和以前一样,我们可以更新这段代码以在成功时刷新页面,但是对于这个例子,我们只是在浏览器中刷新页面。图 8-7 显示了刷新后的页面,其中列表不再显示在左侧导航中。

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

图 8-7。

The deleted list has been removed from the left navigation

使用列表项目

SharePoint 中唯一比列表更丰富的是列表项。您会发现,您在 SharePoint 中的许多交互都与列表项有关,因此您的许多代码也会涉及到它们。在这一节中,我们将探索一些通过代码使用列表项的方法。

获取列表项目

在这个例子中,我们将简单地检索一些列表项,并将它们显示给用户。

超文本标记语言

在 Visual Studio 中创建新的 HTML 文件,并将其命名为 JSOMGetListItems.html。这个示例的 HTML 继续遵循前面示例的极简模式,它由以下几行组成:

<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.js"></script>

<script type="text/javascript" src="/apress/webparts/chapter 8/JSOMGetListItems.js"></script>

<div id="divListItems"></div>

对于这个例子,我们将简单地从演示列表中获取所有的列表项,并将它们显示在页面上的divListItems DIV 中。

Java Script 语言

在 Visual Studio 中创建一个新的 JavaScript 文件,并将其命名为 JSOMGetListItems.js。检索列表项的脚本应该与我们到目前为止看到的其他脚本非常相似,它由以下几行组成:

$(function () {

retrieveListItems();

});

function retrieveListItems() {

var clientContext = new SP.ClientContext();

var oList = clientContext.get_web().get_lists().getByTitle('Demo List');

var camlQuery = new SP.CamlQuery();

this.collListItem = oList.getItems(camlQuery);

clientContext.load(collListItem);

clientContext.executeQueryAsync(

Function.createDelegate(this, this.onQuerySucceeded),

Function.createDelegate(this, this.onQueryFailed)

);

}

function onQuerySucceeded(sender, args) {

var listItemInfo = '';

var listItemEnumerator = collListItem.getEnumerator();

while (listItemEnumerator.moveNext()) {

var oListItem = listItemEnumerator.get_current();

listItemInfo += '<strong>ID: </strong> ' + oListItem.get_id() +

' <strong>Title:</strong> ' + oListItem.get_item('Title') +

'<br />';

}

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

}

function onQueryFailed(sender, args) {

alert('Request failed. ' + args.get_message() +

'\n' + args.get_stackTrace());

}

对于这个例子,由于我们将从列表中获取所有的条目,我们将使用 jQuery Document.ready函数调用retrieveListItems()函数。在获得对客户端上下文的引用后,我们用下面的代码行获得对演示列表的引用:

var oList = clientContext.get_web().get_lists().getByTitle('Demo List');

乍一看,这一行似乎很吓人,因为它很长。然而,它实际上很容易阅读。首先,我们获取当前网站,然后获取网站中的所有列表,最后,我们根据标题获取列表。JSOM 和 REST 在查询对象时都遵循这种类型的模式,使得代码易于理解。接下来,我们需要创建一个 CAML 查询,让 SharePoint 知道我们正在查找哪些项目:

var camlQuery = new SP.CamlQuery();

this.collListItem = oList.getItems(camlQuery);

CAML(协作应用标记语言)查询是一种在 SharePoint 中用于定义列表项查询的查询语言。您可以根据类似 SQL 查询的标准指定要返回的项目,尽管它们看起来一点也不像。在这个例子中,我们简单地使用新的SP.CamlQuery()方法创建一个空查询。查询列表时,即使没有定义参数,也必须提供 CAML 查询。如果您传递一个空的查询,就像在这个例子中,您实际上是要求返回所有的条目。实际上,这不是一个好主意,因为很多列表包含成百上千的条目。在我们创建了查询之后,我们将它传递给oList.getItems()方法来执行查询。正如在其他例子中一样,我们使用了一个名为collListItems的全局变量,并使用了this关键字。最后,我们“加载”查询并执行它。

Note

CAML 查询是一个相当复杂和深刻的话题。在这本书里,我们只触及 CAML 的皮毛;它有那么大。我们将在下一节更深入地探讨 CAML,但是您可以在 http://msdn.microsoft.com/en-us/library/ms467521(v=office.15).aspx 了解更多关于如何构建这些查询的信息。

一旦我们检索到列表项,我们就在onQuerySucceeded函数中处理它们:

function onQuerySucceeded(sender, args) {

var listItemInfo = '';

var listItemEnumerator = collListItem.getEnumerator();

while (listItemEnumerator.moveNext()) {

var oListItem = listItemEnumerator.get_current();

listItemInfo += '<strong>ID: </strong> ' + oListItem.get_id() +

' <strong>Title:</strong> ' + oListItem.get_item('Title') +

'<br />';

}

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

}

这个函数从声明一个名为listItemInfo的空变量开始。这个变量将保存将在页面上显示的整个 HTML。接下来,我们获得了collListItem变量的枚举器,您会记得它在从 SharePoint 返回的任何项目集合上都可用。我们使用listItemEnumerator.moveNext()方法循环遍历条目。在循环内部,我们使用listItemEnumerator.get_current()方法获取每个项目。然后,我们为结果集中显示 ID 和标题的每一项构建一些 HTML,并将其填充到listItemInfo变量中。最后,我们用 jQuery 将 HTML 设置为页面上的divListItems DIV。

结果

将内容编辑器 Web 部件的内容链接属性设置为 HTML 文件,并保存页面。页面现在将显示演示列表中的所有项目,如图 8-8 所示。

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

图 8-8。

List items from the Demo List displayed in the Content Editor Web Part

用 CAML 查询限制结果

正如我提到的,查询列表中的所有项目通常不是一个好主意。当然,有时候这是需要的或者有意义的;例如,您可能有一个项目很少的列表,或者您有一个需要查看所有项目的管理员任务。如果您过去使用过 SharePoint,您应该知道 SharePoint 会自动限制列表结果,默认情况下一个查询会有 2,000 个结果。在任一情况下,大多数用户都不需要查看列表中的所有项目,并且查询将被限制为仅显示用户需要查看的项目。

CAML 允许您基于各种各样的参数来限制结果,这使您可以完全控制向用户显示什么。在前面的例子中,我们通过创建一个新的SP.CamlQuery对象来传递一个空的 CAML 查询,该对象返回所有的列表项。您可以通过对CamlQuery对象使用set_viewXml()方法来传递 CAML 查询,如下面的“JavaScript”部分所示。

Java Script 语言

更新前一个示例中的JSOMGetListItems.js,并用以下代码行更新声明SP.CamlQuery()对象的部分:

var camlQuery = new SP.CamlQuery();

camlQuery.set_viewXml(

'<View><Query><Where><Geq><FieldRef Name=\'ID\'/>' +

'<Value Type=\'Number\'>5</Value></Geq></Where></Query>' +

'<RowLimit>10</RowLimit></View>'

);

this.collListItem = oList.getItems(camlQuery);

在本例中,我们通过指定只需要 ID 大于或等于 5 的项目来限制结果。这是通过使用代表“大于或等于”的GEQ元素来完成的在GEQ元素之前,我们使用一个Where元素并指定 ID 的FieldRef,它是列表项的 ID。如果这些看起来像拉丁语,不要担心,你可以下载一些工具来帮助你写 CAML。我们不会深入研究编写 CAML 查询的细节;对于这一部分,您应该明白,您可以非常详细地调整您的查询。

Note

乍一看,CAML 可能显得相当混乱和过于复杂。当你和 CAML 一起工作了一段时间后,你可能还在想同样的事情!幸运的是,有几个很棒的免费工具可以帮助你制作你的 CAML 报表。我个人喜欢 SharePoint CAML 查询助手,它是免费的,可以在 CodePlex 上下载。访问 https://spcamlqueryhelper.codeplex.com 下载一份。

结果

更新 JavaScript 文件并上传,覆盖之前的版本。使用内容编辑器 Web 部件刷新页面,您将看到结果现在只显示 ID 大于或等于 5 的项目,如图 8-9 所示。

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

图 8-9。

The results of the Demo List query limited by a CAML query

添加列表项目

在本例中,我们将向演示列表添加一个新项目。

超文本标记语言

在 Visual Studio 中创建新的 HTML 文件,并将其命名为JSOMAddListItems.html。该页面的标记将允许用户向演示列表添加一个项目,提供标题和描述。它由以下几行组成:

<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.js"></script>

<script type="text/javascript" src="/apress/Webparts/chapter 8/JSOMAddListItems.js"></script>

<div id="AddListData">

<div>

Title:

<br />

<input type="text" id="txtTitle" />

</div>

<div>

Description:

<br />

<textarea cols="20" id="txtDesc"></textarea>

</div>

<br />

<div>

<input id="btnSubmit" type="button" value="Submit" />

</div>

</div>

<div id="divResult"></div>

我们为列表项标题提供文本类型的输入,并为描述提供文本区域。页面上的每个元素都有一个 ID,这样我们就可以很容易地用 jQuery 找到它。

Java Script 语言

在 Visual Studio 中创建一个新的 JavaScript 文件,并将其命名为 JSOMADDListItems.js。它由以下几行组成:

$(function () {

bindButtonClick();

});

function bindButtonClick() {

$("#btnSubmit").on("click", function () {

addListItem();

});

}

function addListItem() {

var title = $("#txtTitle").val();

var desc = $("#txtDesc").val();

var clientContext = new SP.ClientContext();

var oList = clientContext.get_web().get_lists().getByTitle('Demo List');

var itemCreateInfo = new SP.ListItemCreationInformation();

this.oListItem = oList.addItem(itemCreateInfo);

oListItem.set_item('Title', title);

oListItem.set_item('Description', desc);

oListItem.set_item('Status', 'On-time');

oListItem.update();

clientContext.load(oListItem);

clientContext.executeQueryAsync(

Function.createDelegate(this, this.onAddSucceeded),

Function.createDelegate(this, this.onAddFailed)

);

}

function onAddSucceeded(sender, args) {

$("#divResult").html("Item successfully added!");

}

function onAddFailed(sender, args) {

alert('Request failed. ' + args.get_message() +

'\n' + args.get_stackTrace());

}

在我们用 jQuery 附加了一个按钮点击事件之后,我们在点击事件上做的第一件事就是获取用户用下面几行提供的值:

var title = $("#txtTitle").val();

var desc = $("#txtDesc").val();

接下来,我们获取对当前客户端上下文的引用,以及演示列表。然后,为了创建一个新的列表项,我们必须实例化一个SP.ListItemCreationInformation对象。此对象允许您为列表创建新的列表项并设置其属性。这是通过以下代码完成的:

var itemCreateInfo = new SP.ListItemCreationInformation();

this.oListItem = oList.addItem(itemCreateInfo);

oListItem.set_item('Title', title);

oListItem.set_item('Description', desc);

oListItem.set_item('Status', 'On-time');

oListItem.update();

一旦我们创建了一个新的SP.ListItemCreationInformation对象,我们使用 list 对象上的addItem()方法将它添加到列表中。接下来,我们使用set_item()方法在列表项对象上设置单独的属性。这个方法有两个参数。第一个参数是要为其设置值的字段或列,第二个参数是值本身。对于标题和描述,我们只需传入之前检索到的值。对于 Status 列,我们简单地将 On-time 硬编码为一个值。最后,我们使用update()方法更新项目,然后将其加载到客户机上下文中并执行查询。在success函数中,我们简单地向屏幕输出列表项创建成功。

结果

将内容编辑器 Web 部件的内容链接属性设置为 HTML 文件,并保存页面。页面将显示供用户输入详细信息的文本框,然后在添加项目时显示成功消息,如图 8-10 所示。

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

图 8-10。

Adding a new item to the Demo List

然后,我们可以导航到演示列表,以确认添加了新项目。图 8-11 显示了添加了新列表项和 HTML 页面提供的值的演示列表。

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

图 8-11。

A new list item added to the Demo List

删除列表项目

这个例子将向你展示如何删除列表项,在这种情况下,我们将删除我们在上一个例子中添加的项目。

超文本标记语言

在 Visual Studio 中创建新的 HTML 文件,并将其命名为 JSOMDeleteListItems.html。这个文件的 HTML 要小得多,因为我们需要从用户那里获取的只是一个对应于他们想要删除的列表项的 ID。这是通过以下代码行实现的:

<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.js"></script>

<script type="text/javascript" src="/apress/Webparts/chapter 8/JSOMDeleteListItems.js"></script>

<div>

Enter ID to Delete: <input type="text" id="txtId" />

</div>

<div>

<input id="btnSubmit" type="button" value="Submit" />

</div>

<div id="divResult"></div>

这个例子过于简单,因为用户很可能不知道要删除的某个列表项的 ID。一个更真实的例子可能是向用户显示一个项目列表,并允许他们单击一个项目来删除它。在这种情况下,页面上会有列表项 id,并且可以很容易地访问它。我们将保留一个简单的文本框来简化这个例子。

Java Script 语言

在 Visual Studio 中创建新的 JavaScript 文件,并将其命名为 JSOMDeleteListItems.js 包括以下代码:

$(function () {

bindButtonClick();

});

function bindButtonClick() {

$("#btnSubmit").on("click", function () {

deleteListItem();

});

}

function deleteListItem() {

var id = $("#txtId").val();

var clientContext = new SP.ClientContext();

var oList = clientContext.get_web().get_lists().getByTitle('Demo List');

this.oListItem = oList.getItemById(id);

oListItem.deleteObject();

clientContext.executeQueryAsync(

Function.createDelegate(this, this.onQuerySucceeded),

Function.createDelegate(this, this.onQueryFailed)

);

}

function onQuerySucceeded(sender, args) {

$("#divResult").html("Item successfully deleted!");

}

function onQueryFailed(sender, args) {

alert('Request failed. ' + args.get_message() +

'\n' + args.get_stackTrace());

}

页面上的按钮点击事件将调用deleteListItem()函数。使用下面的代码行,我们要做的第一件事是获取用户在页面上输入的 ID:

var id = $("#txtId").val();

接下来,我们获得当前的客户端上下文和对演示列表的引用。删除项目是通过以下几行完成的:

this.oListItem = oList.getItemById(id);

oListItem.deleteObject();

我们在 list 对象上使用getItemById()方法,传递用户提交的 ID。然后,我们调用deleteObject()方法来实际执行删除。与本章前面的删除列表类似,这是删除列表项所需的全部内容。我们不需要将删除调用加载到客户端上下文中;我们只需要执行查询。success函数将简单地通知用户删除成功。

结果

将内容编辑器 Web 部件的内容链接属性设置为 HTML 文件,并保存页面。页面会显示供用户输入 ID 的文本框,当删除一项时会显示成功消息,如图 8-12 所示。

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

图 8-12。

Deleting a list item using JSOM

使用文档库

因为 SharePoint 的优势之一在于文档管理,所以您需要知道如何通过代码使用文档库。因为文档库实际上只是 SharePoint 中的列表,所以您在这方面已经有了一些经验!

创建新文件夹

在本例中,我们将演示如何在现有文档库中创建新文件夹。

超文本标记语言

在 Visual Studio 中创建新的 HTML 文件,并将其命名为 JSOMCreateFolder.html。这个页面的标记非常简单,允许用户输入他们希望创建的文件夹的名称。它由以下几行组成:

<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.js"></script>

<script type="text/javascript" src="/apress/Webparts/chapter 8/JSOMCreateFolder.js"></script>

<div>

<strong>Enter a name for the folder:</strong>

<input type="text" id="txtFolderName" />

<input type="button" id="btnSubmit" value="Submit" />

</div>

<div id="divResults"></div>

Java Script 语言

在 Visual Studio 中创建新的 JavaScript 文件,命名为 JSOMCreateFolder.js 包括以下代码:

$(function () {

bindButtonClick();

});

function bindButtonClick() {

$("#btnSubmit").on("click", function () {

createFolder();

});

}

function createFolder() {

var folderName = $("#txtFolderName").val();

var clientContext = new SP.ClientContext();

var oWebsite = clientContext.get_web();

var oList = oWebsite.get_lists().getByTitle("Documents");

var folderCreateInfo = new SP.ListItemCreationInformation();

folderCreateInfo.set_underlyingObjectType(SP.FileSystemObjectType.folder);

folderCreateInfo.set_leafName(folderName);

this.oListItem = oList.addItem(folderCreateInfo);

this.oListItem.update();

clientContext.load(oList);

clientContext.executeQueryAsync(

Function.createDelegate(this, this.onQuerySucceeded),

Function.createDelegate(this, this.onQueryFailed)

);

}

function onQuerySucceeded() {

$("#divResults").html("Folder successfully created!");

}

function onQueryFailed(sender, args) {

alert('Request failed. ' + args.get_message() +

'\n' + args.get_stackTrace());

}

在使用 jQuery 连接按钮点击之后,createFolder()函数从获取用户在页面上输入的文件夹名称开始:

var folderName = $("#txtFolderName").val();

接下来,我们获取一个对当前客户端上下文和当前站点的引用,然后用下面一行引用共享文档文件夹:

var oList = oWebsite.get_lists().getByTitle("Documents");

本示例将在共享文档库中新建一个文件夹。因为所有文档库实际上都是 SharePoint 中的列表,所以我们可以使用getLists().getByTitle()方法来检索该库。接下来,我们为文件夹创建一个新的SP.ListItemCreationInformation对象:

var folderCreateInfo = new SP.ListItemCreationInformation();

乍一看,这似乎很奇怪,因为我们正在创建一个新文件夹,而不是一个列表项。在 SharePoint 中,文件夹是列表项,尽管它们的外观和行为就像您对文件夹的期望一样。因此,使用相同的SP.ListItemCreationInformation对象。既然已经创建了对象,我们需要使用下面几行设置一些属性:

folderCreateInfo.set_underlyingObjectType(SP.FileSystemObjectType.folder);

folderCreateInfo.set_leafName(folderName);

this.oListItem = oList.addItem(folderCreateInfo);

this.oListItem.update();

首先,由于这不是一个标准的列表项,我们需要使用set_underlyingObjectType()方法指定对象类型,将SP.FileSystemObjectType.folder作为参数传入。接下来,我们使用set_leafName()方法设置文件夹名称,传递用户从页面提交的名称。最后,我们将新文件夹添加到列表中并更新它,然后在客户机上下文中加载查询。success功能将简单地向屏幕输出一条消息,通知用户文件夹已成功创建。

结果

将内容编辑器 Web 部件的内容链接属性设置为 HTML 文件,并保存页面。页面会显示文本框,供用户输入要创建的文件夹的名称,完成后会显示成功消息,如图 8-13 所示。

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

图 8-13。

Creating a new folder with JSOM

然后,我们可以导航到文档库,直观地验证新文件夹是否已创建,如图 8-14 所示。

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

图 8-14。

New folder created via JSOM

使用文件

列表和库并不是您的编码技能将被使用的唯一领域。在这一节中,我们将看看如何通过代码处理文件。

创建新文件

在本例中,我们将创建一个新的文本文件,并将其添加到文档库中。

超文本标记语言

在 Visual Studio 中创建新的 HTML 文件,并将其命名为 JSOMCreateDocument.html。该页面的标记将允许用户输入新文本文件的名称,以及文件本身的内容。它由以下几行组成:

<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.js"></script>

<script type="text/javascript" src="/apress/Webparts/chapter 8/JSOMCreateDocument.js"></script>

<div id="CreateFile">

<div>

<strong>Enter a title for the document:</strong>

<br />

<input type="text" id="txtDocumentTitle" />

</div>

<div>

<strong>Enter content for the document:</strong>

<br />

<textarea cols="20" id="txtDocumentContent"></textarea>

</div>

<br />

<input type="button" id="btnSubmit" value="Submit" />

</div>

<div id="divResults"></div>

Java Script 语言

在 Visual Studio 中创建新的 JavaScript 文件,命名为 JSOMCreateDocument.js 包括以下代码:

$(function () {

bindButtonClick();

});

function bindButtonClick() {

$("#btnSubmit").on("click", function () {

createDocument();

});

}

function createDocument() {

var docTitle = $("#txtDocumentTitle").val() + ".txt";

var docContent = $("#txtDocumentContent").val();

var clientContext = new SP.ClientContext();

var oWebsite = clientContext.get_web();

var oList = oWebsite.get_lists().getByTitle("Documents");

var fileCreateInfo = new SP.FileCreationInformation();

fileCreateInfo.set_url(docTitle);

fileCreateInfo.set_content(new SP.Base64EncodedByteArray());

for (var i = 0; i < docContent.length; i++) {

fileCreateInfo.get_content().append(docContent.charCodeAt(i));

}

this.newFile = oList.get_rootFolder().get_files().add(fileCreateInfo);

clientContext.load(this.newFile);

clientContext.executeQueryAsync(

Function.createDelegate(this, this.onQuerySucceeded),

Function.createDelegate(this, this.onQueryFailed)

);

}

function onQuerySucceeded() {

$("#divResults").html("Document successfully created!");

}

function onQueryFailed(sender, args) {

alert('Request failed. ' + args.get_message() +

'\n' + args.get_stackTrace());

}

我们需要做的第一件事是获取用户在页面上输入的文档标题和内容。这是通过以下代码行实现的:

var docTitle = $("#txtDocumentTitle").val() + ".txt";

var docContent = $("#txtDocumentContent").val();

注意,我们在文档标题的末尾添加了.txt。这将让 SharePoint 知道我们打算创建一个文本文件,因为它将使用名称中的扩展名来确定文件类型。接下来,我们获得对当前客户机上下文的引用,以及我们想要保存新文档的 web 和文档库。现在我们需要创建一个新的SP.FileCreationInformation对象并设置它的属性:

var fileCreateInfo = new SP.FileCreationInformation();

fileCreateInfo.set_url(docTitle);

fileCreateInfo.set_content(new SP.Base64EncodedByteArray());

现在,您应该开始看到使用 SharePoint 在 JavaScript 中创建对象的模式。您创建的任何东西都有一个与之相关联的CreationInformation对象。一旦创建了对象,我们就使用set_url()方法设置文件的 URL。最后,我们使用SP.Base64EncodedByteArray()对象将文件的内容设置为一个空字节数组。你暂时不需要太担心这个对象的细节;要知道这是 JSOM 代码在设置新文件内容时所期望的。现在我们已经创建了空数组,我们需要使用以下代码填充它:

for (var i = 0; i < docContent.length; i++) {

fileCreateInfo.get_content().append(docContent.charCodeAt(i));

}

这是一个简单的循环,将用户提交的文本中的每个字符添加到文件内容的空数组中。一旦循环完成,文本被输入到文档中,我们就将它添加到库中:

this.newFile = oList.get_rootFolder().get_files().add(fileCreateInfo);

然后,我们在客户机上下文中加载查询并执行它。success功能将简单地向屏幕输出文件创建成功。

Note

在本例中,我们正在创建一个简单的文本文件。在大多数实际情况下,文本文件可能不是预期的结果,但可能是 Word 文件或 Excel 文件。您完全可以通过简单地将.txt更改为.docx来更改这个示例以生成一个 Word 文档。实际上,这个简单的更改会创建一个包含内容的新 Word 文档。但是,它只能在客户端计算机上的 Word 中打开,而不能在 Office Web Apps 中打开。幸运的是,微软提供了 Office JavaScript 文件,允许您从浏览器创建和操作 Office 文件。你可以在 http://msdn.microsoft.com/en-us/library/office/fp160953%28v=office.15%29.aspx 找到更多信息。

结果

将内容编辑器 Web 部件的内容链接属性设置为 HTML 文件,并保存页面。页面将显示文本框,供用户输入文档的标题和内容,然后在新文档创建完成后显示成功消息,如图 8-15 所示。

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

图 8-15。

Creating a new document from a Content Editor Web Part

我们可以导航到 Documents 文件夹,发现新的文本文档已经创建。您可以单击该文档,它将在浏览器中打开,并显示用户从页面中输入的内容,如图 8-16 所示。

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

图 8-16。

New text document created in the Documents folder

阅读文件

在这一节中,我们将看到如何读取我们在前一个例子中创建的文件。

超文本标记语言

在 Visual Studio 中创建新的 HTML 文件,并将其命名为 JSOMReadDocument.html。这个页面的标记非常简单,只有一个对定制 JavaScript 文件的引用和一个输出文档内容的 DIV。它由以下几行组成:

<script type="text/javascript" src="/apress/Webparts/chapter 8/JSOMReadDocument.js"></script>

<div id="divReadDocument" />

Java Script 语言

在 Visual Studio 中创建新的 JavaScript 文件,命名为 JSOMReadDocument.js 包括以下代码:

$(function () {

readDocument();

});

function readDocument() {

var siteUrl = _spPageContextInfo.webAbsoluteUrl;

var documentLibrary = "/Shared Documents/"

var fileUrl = "New Text Doc.txt";

var fullUrl = siteUrl + documentLibrary + fileUrl;

$.ajax({

url: fullUrl,

type: "GET"

})

.done(function (data) {

$("#divReadDocument").html(data);

})

.fail(function () {

alert("error");

});

}

乍一看,这段代码应该很简洁,您会注意到这里根本没有 JSOM 代码。从 SharePoint 读取文本文件的美妙之处在于,您所需要的只是 jQuery。因为这是关于 JSOM 的一章,这段代码应该在别的地方,但是因为我们创建了一个文档,你也应该知道如何阅读它。有一个简单的 jQuery Document.ready函数,它将触发代码来读取文件。我们有意保持代码简单,并对我们刚刚创建的文档的文件名进行硬编码:

var siteUrl = _spPageContextInfo.webAbsoluteUrl;

var documentLibrary = "/Shared Documents/"

var fileUrl = "New Text Doc.txt";

var fullUrl = siteUrl + documentLibrary + fileUrl;

我们做的第一件事是通过使用_spPageContextInfo.webAbsoluteUrl获得当前网站的完整 URL。接下来,我们对 URL 的文档库部分和文件名进行硬编码。最后,我们将它们放入一个名为fullUrl的新变量。您完全可以在一行中完成所有这些工作,但是您会发现,如果您将代码分成几行,以后调试代码会更容易。一旦我们有了文件的 URL,我们就使用 jQuery AJAX 调用来获取文档:

$.ajax({

url: fullUrl,

type: "GET"

})

.done(function (data) {

$("#divReadDocument").html(data);

})

.fail(function () {

alert("error");

});

当在 jQuery 中通过 AJAX 检索文本文件时,内容将以文本形式返回,我们可以简单地将它输出到页面,无需任何修改。我们使用 jQuery .done函数,将文件内容设置为一个名为data的新变量。然后,我们将数据设置为页面上结果 DIV 的 HTML。

Note

和以前一样,当创建一个新文件时,我们通过使用文本文件来保持事情的简单。这也适用于本节和读取文件。使用上述方法无法读取 Office 文件。您需要利用 Office JavaScript 文件在浏览器中正确读取 Word 文件或 Excel 文件。你可以在 http://msdn.microsoft.com/en-us/library/office/fp160953%28v=office.15%29.aspx 找到更多信息。

结果

将内容编辑器 Web 部件的内容链接属性设置为 HTML 文件,并保存页面。页面将显示文本文件的内容,如图 8-17 所示。

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

图 8-17。

Contents of the text file displayed on the page

更新文件

您还可以使用 JSOM 轻松更新文件。事实上,更新文件与创建文件的代码基本相同,只是增加了一行代码:

fileCreateInfo.set_overwrite(true);

这一行只是告诉 SharePoint 覆盖以前的同名文件。使用它,您可以轻松地将文本文件的内容读入页面上的文本框,并允许用户修改内容。当用户希望保存文件时,使用与创建文件相同的代码,并包含覆盖命令。

删除文件

在这个例子中,我们将看到如何删除一个文件。

超文本标记语言

在 Visual Studio 中创建新的 HTML 文件,并将其命名为 JSOMDeleteDocument.html。该页面的标记有一个文本框,用户可以输入他们希望删除的文件的名称。它由以下几行组成:

<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.js"></script>

<script type="text/javascript" src="/apress/Webparts/chapter 8/JSOMDeleteDocument.js"></script>

<div id="DeleteFile">

<div>

<strong>Enter the name of document to delete:</strong>

<br />

<input type="text" id="txtDocumentTitle" />

</div>

<br />

<input type="button" id="btnSubmit" value="Submit" />

</div>

<div id="divResults"></div>

Java Script 语言

在 Visual Studio 中创建新的 JavaScript 文件,命名为 JSOMDeleteDocument.js 包括以下代码:

$(function () {

bindButtonClick();

});

function bindButtonClick() {

$("#btnSubmit").on("click", function () {

deleteDocument();

});

}

function deleteDocument() {

var docTitle = $("#txtDocumentTitle").val() + ".txt";

var clientContext = new SP.ClientContext();

var oWebsite = clientContext.get_web();

var fileUrl = _spPageContextInfo.webServerRelativeUrl +

"/Shared Documents/" + docTitle;

this.fileToDelete = oWebsite.getFileByServerRelativeUrl(fileUrl);

this.fileToDelete.deleteObject();

clientContext.executeQueryAsync(

Function.createDelegate(this, this.onQuerySucceeded),

Function.createDelegate(this, this.onQueryFailed)

);

}

function onQuerySucceeded() {

$("#divResults").html("Document successfully deleted!");

}

function onQueryFailed(sender, args) {

alert('Request failed. ' + args.get_message() +

'\n' + args.get_stackTrace());

}

在连接了按钮点击事件之后,我们做的第一件事就是获取用户想要删除的文档的标题:

var docTitle = $("#txtDocumentTitle").val() + ".txt";

我们将保持这个例子的简单,删除之前创建的文本文件,从而将.txt扩展硬编码到代码中。接下来,我们执行引用当前客户端上下文和 web 的惯例,然后我们构造文档的路径:

var fileUrl = _spPageContextInfo.webServerRelativeUrl +

"/Shared Documents/" + docTitle;

对于这个路径,我们只需要文档的相对路径,而不需要完整的 URL。我们可以通过使用_spPageContextInfo.webServerRelativeUrl获得当前网页的相对路径。因为我们知道这个文档位于 Documents 文件夹中,所以我们将对其进行硬编码,并添加用户提交的文档标题。就像 SharePoint 中的其他删除操作一样,我们不需要在客户端上下文中加载这个请求,只需调用deleteObject方法并执行查询。success功能将向用户输出一条消息,通知他们文档已被删除。

与我们之前看到的创建、读取和更新文档的功能不同,假设用户拥有删除权限,您可以使用 JSOM 删除您想要的任何文件。SharePoint 在删除文档方面是相当不可知的。您可以很容易地使用相同的代码删除 Office 文档,而没有任何问题或额外的 JavaScript 库。

结果

将内容编辑器 Web 部件的内容链接属性设置为 HTML 文件,并保存页面。页面将显示一个文本框,供用户输入文档标题,并显示结果消息,如图 8-18 所示。

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

图 8-18。

Deleting a file via JSOM

使用站点

在这一点上,你可能会想,JSOM 是相当强大的!事实上是的,为了证明这一点,我们将创建一个新的网站!使用列表和库很酷,但是能够通过 JavaScript 创建一个新的站点将真正展示 JSOM 的力量。

创建网站

在本例中,我们将创建一个新的团队站点。除了创建新站点,我们还将设置它的许多属性,包括标题、描述和站点模板。

超文本标记语言

在 Visual Studio 中创建新的 HTML 文件,并将其命名为 JSOMCreateSite.html。该页面的标记有一个供用户输入新站点名称的文本框,以及一个用于站点描述的文本框。它由以下几行组成:

<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.js"></script>

<script type="text/javascript" src="/apress/Webparts/chapter 8/JSOMCreateSite.js"></script>

<div id="DeleteFile">

<div>

<strong>Enter the name of the site:</strong>

<br />

<input type="text" id="txtSiteTitle" />

</div>

<br />

<div>

<strong>Enter site description:</strong>

<br />

<textarea cols="20" id="txtSiteDescription"></textarea>

</div>

<br />

<input type="button" id="btnSubmit" value="Submit" />

</div>

<div id="divResults"></div>

Java Script 语言

在 Visual Studio 中创建新的 JavaScript 文件,命名为 JSOMCreateSite.js 包括以下代码:

$(function () {

bindButtonClick();

});

function bindButtonClick() {

$("#btnSubmit").on("click", function () {

createSite();

});

}

function createSite() {

var siteTitle = $("#txtSiteTitle").val();

var siteDesc = $("#txtSiteDescription").val();

var siteUrl = siteTitle.replace(/\s/g, "");

var clientContext = new SP.ClientContext();

var collWeb = clientContext.get_web().get_webs();

var webCreationInfo = new SP.WebCreationInformation();

webCreationInfo.set_title(siteTitle);

webCreationInfo.set_description(siteDesc);

webCreationInfo.set_language(1033);

webCreationInfo.set_url(siteUrl);

webCreationInfo.set_useSamePermissionsAsParentSite(true);

webCreationInfo.set_webTemplate('STS#0');

var oNewWebsite = collWeb.add(webCreationInfo);

clientContext.executeQueryAsync(

Function.createDelegate(this, this.onQuerySucceeded),

Function.createDelegate(this, this.onQueryFailed)

);

}

function onQuerySucceeded() {

$("#divResults").html("Site successfully created!");

}

function onQueryFailed(sender, args) {

alert('Request failed. ' + args.get_message() +

'\n' + args.get_stackTrace());

}

创建一个新的站点需要更多的代码,但是现在应该已经非常熟悉了。首先,我们使用下面几行获取用户提交的标题和描述:

var siteTitle = $("#txtSiteTitle").val();

var siteDesc = $("#txtSiteDescription").val();

var siteUrl = siteTitle.replace(/\s/g, "");

创建网站时,除了标题之外,还必须提供网站的 URL。对于这个例子,我们将简单地获取用户为标题输入的文本,并删除所有空格以生成 URL。这是使用 JavaScript 中的replace()方法完成的,第一个参数是我们要搜索的内容,第二个参数是应该替换的内容。/\s/g文本表示一个空格,必须用于此功能才能正常工作。

一旦我们有了创建站点所需的变量,我们就引用当前的客户端上下文,然后获取当前站点中的站点集合:

var collWeb = clientContext.get_web().get_webs();

方法返回当前站点中所有子站点的集合。我们最终要将新站点添加到这个集合中。接下来,我们创建一个SP.WebCreationInformation对象:

var webCreationInfo = new SP.WebCreationInformation();

webCreationInfo.set_title(siteTitle);

webCreationInfo.set_description(siteDesc);

webCreationInfo.set_language(1033);

webCreationInfo.set_url(siteUrl);

webCreationInfo.set_useSamePermissionsAsParentSite(true);

webCreationInfo.set_webTemplate('STS#0');

就像我们之前看到的其他CreationInformation对象一样,我们创建一个新的WebCreationInformation对象并设置它的各种属性。幸运的是,在这个对象上配置属性所需的所有方法都是不言自明的;例如,set_useSamePermissionsAsParentSite()决定这个新站点是否应该继承父站点的权限。有一些您可能不熟悉的棘手参数,例如1033(在为站点设置语言时表示“英语”)和STS#0(在设置站点模板时表示团队站点模板)。所有其他属性应该看起来很熟悉。

设置好属性后,我们只需将新站点添加到集合中:

var oNewWebsite = collWeb.add(webCreationInfo);

创建新站点也是另一个不需要在客户机上下文中加载查询的领域。您可以简单地执行查询来创建新站点。success功能将简单地通知用户站点已经创建。

Note

同样,这些示例中的代码在当前用户的权限级别下运行。由于这些示例中有许多执行更高级的功能,如创建和删除 SharePoint 对象,因此用户需要有适当的权限来执行这些功能。值得再次指出这一点,因为站点创建需要用户对创建新站点的站点拥有完全控制权限。

结果

将内容编辑器 Web 部件的内容链接属性设置为 HTML 文件,并保存页面。页面将显示文本框供用户输入新的站点标题和描述,并显示结果消息,如图 8-19 所示。

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

图 8-19。

Creating a new site via JSOM

然后,我们可以打开创建新站点的站点内容页面,并滚动到底部。在子站点部分,我们可以看到新站点已经创建,如图 8-20 所示。

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

图 8-20。

The newly created subsite in the Site Contents page

删除网站

在这一节中,我们将删除我们在前一个例子中创建的站点。

超文本标记语言

在 Visual Studio 中创建新的 HTML 文件,并将其命名为 JSOMDeleteSite.html。这个页面的标记有一个文本框,用户可以输入他们想要删除的站点的名称。它由以下几行组成:

<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.js"></script>

<script type="text/javascript" src="/apress/Webparts/chapter 8/JSOMDeleteSite.js"></script>

<div id="DeleteFile">

<div>

<strong>Enter the name of the site to delete:</strong>

<br />

<input type="text" id="txtSiteTitle" />

</div>

<br />

<input type="button" id="btnSubmit" value="Submit" />

</div>

<div id="divResults"></div>

Java Script 语言

在 Visual Studio 中创建新的 JavaScript 文件,命名为 JSOMDeleteSite.js 包括以下代码:

$(function () {

bindButtonClick();

});

function bindButtonClick() {

$("#btnSubmit").on("click", function () {

deleteSite();

});

}

function deleteSite() {

var siteTitle = $("#txtSiteTitle").val();

var siteTitleNoSpaces = siteTitle.replace(/\s/g, "");

var siteUrl = _spPageContextInfo.webAbsoluteUrl + "/" + siteTitleNoSpaces;

var clientContext = new SP.ClientContext(siteUrl);

var oWebsite = clientContext.get_web();

oWebsite.deleteObject();

clientContext.executeQueryAsync(

Function.createDelegate(this, this.onQuerySucceeded),

Function.createDelegate(this, this.onQueryFailed)

);

}

function onQuerySucceeded() {

$("#divResults").html("Site successfully deleted!");

}

function onQueryFailed(sender, args) {

alert('Request failed. ' + args.get_message() +

'\n' + args.get_stackTrace());

}

就像前面的例子一样,我们获取用户输入的网站标题,然后删除所有空格:

var siteTitle = $("#txtSiteTitle").val();

var siteTitleNoSpaces = siteTitle.replace(/\s/g, "");

var siteUrl = _spPageContextInfo.webAbsoluteUrl + "/" + siteTitleNoSpaces;

一旦我们有了标题,并删除了空格,我们需要构建一个完整的网站 URL。我们可以通过使用_spPageContextInfo.webAbsoluteUrl获得当前站点的完整 URL,只需附加一个/和站点标题,末尾不带空格。我们需要构造一个完整的 URL,以便我们可以请求我们希望删除的站点的客户端上下文,而不是用户所在的当前站点:

var clientContext = new SP.ClientContext(siteUrl);

var oWebsite = clientContext.get_web();

到目前为止,我们一直使用用户查看页面的当前站点的客户端上下文。但是,您可以通过将 URL 作为参数传递给SP.ClientContext()方法来请求另一个站点的上下文,就像我们在本例中所做的那样。一旦我们有了站点的上下文,我们就可以通过使用clientContext.get_web()获得对该站点中根站点的引用。就像所有其他删除操作一样,我们简单地调用deleteObject()方法来请求删除操作:

oWebsite.deleteObject();

success功能将向用户显示一条消息,通知他们删除已经发生。

结果

将内容编辑器 Web 部件的内容链接属性设置为 HTML 文件,并保存页面。页面会显示一个文本框供用户输入站点标题,并显示结果信息,如图 8-21 所示。

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

图 8-21。

Deleting a subsite via JSOM

在本例中,我们将删除刚刚创建的站点。导航回站点内容页面将显示该子站点已被成功删除,如图 8-22 所示。

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

图 8-22。

The site has been removed from the root site

使用社交数据

SharePoint 的一大新领域是社交数据。如果你要为 SharePoint 编写定制的解决方案,你肯定会在某些时候遇到访问社交数据的需求。本节将演示如何提取这些数据用于您的解决方案。

超文本标记语言

在 Visual Studio 中创建新的 HTML 文件,并将其命名为 JSOMGetSocialData.html。这个页面的标记将包括几个 div 和一个输出数据的 SPAN。它由以下几行组成:

<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.js"></script>

<script type="text/javascript" src="/_layouts/15/sp.userprofiles.js"></script>

<script type="text/javascript" src="/apress/Webparts/chapter 8/JSOMGetSocialData.js"></script>

<link rel="stylesheet" type="text/css" href="/apress/Webparts/chapter 8/JSOMGetSocialData.css" />

<div id="WelcomeMessage">

Welcome back <span id="WelcomeMessageUserName"></span>

</div>

<div id="UserFollows" />

到目前为止,这个例子比其他任何例子都有更多的引用。你会注意到,除了引用sp.jssp.runtime.js,我们还引用了sp.userprofiles.js。正如本章前面提到的,JSOM 功能包含在许多满足特定需求的不同文件中。在这个例子中,因为我们想要获得用户的社交数据,所以我们必须包含对sp.userprofiles.js文件的引用,以便访问该功能。

我们还将包含一个名为JSOMGetSocialData.css的定制 CSS 文件。这将用于设置脚本输出的样式。所有其他的例子都可以很容易地包含 CSS 样式。在您的定制开发工作中,您会发现样式将在您的许多 web 部件中扮演重要角色;所以这个例子将向你展示包含它是多么容易。

Java Script 语言

在 Visual Studio 中创建新的 JavaScript 文件,命名为 JSOMGetSocialData.js 包括以下代码:

$(function () {

ExecuteOrDelayUntilScriptLoaded(getUserProfileProperties, "sp.userprofiles.js");

});

function getUserProfileProperties() {

var clientContext = new SP.ClientContext();

var peopleManager = new SP.UserProfiles.PeopleManager(clientContext);

this.userProperties = peopleManager.getMyProperties();

clientContext.load(userProperties);

var followingManager = new SP.Social.SocialFollowingManager(clientContext);

this.following = followingManager.getFollowed(15);

clientContext.executeQueryAsync(

Function.createDelegate(this, this.onQuerySucceeded),

Function.createDelegate(this, this.onQueryFailed)

);

}

function onQuerySucceeded() {

$("#WelcomeMessageUserName").text(userProperties.get_displayName());

var followedItems = "Items you are following:<br />";

$.each(following, function( index, value ) {

followedItems += "<a href='" + value.get_uri() + "'>" + value.get_name() + "</a><br />";

});

$("#UserFollows").append(followedItems);

}

function onQueryFailed(sender, args) {

alert('Request failed. ' + args.get_message() +

'\n' + args.get_stackTrace());

}

在 jQuery Document.ready函数中,我们包含了ExecuteOrDelayUntilScriptLoaded内置函数。我们需要使用它,因为我们的 JavaScript 代码依赖于在sp.userprofiles.js中找到的功能,如果它在文件被加载之前运行会导致错误:

ExecuteOrDelayUntilScriptLoaded(getUserProfileProperties, "sp.userprofiles.js");

一旦触发了getUserProfileProperties函数,我们就获得一个对当前客户端上下文的引用,然后用下面的代码创建一个新的PeopleManager对象:

var peopleManager = new SP.UserProfiles.PeopleManager(clientContext);

this.userProperties = peopleManager.getMyProperties();

clientContext.load(userProperties);

我们可以通过使用SP.UserProfiles.PeopleManager()方法创建一个新的PeopleManager对象,将客户端上下文作为其参数传入。PeopleManager对象提供了访问用户数据的方法。在这种情况下,我们可以通过使用peopleManager.getMyProperties()方法,并在客户端上下文中加载userProperties变量来获取当前用户的所有属性。

接下来,我们将通过使用SocialFollowingManager()对象获取用户关注的所有项目:

var followingManager = new SP.Social.SocialFollowingManager(clientContext);

this.following = followingManager.getFollowed(15);

我们可以使用SP.Social.SocialFollowingManager()方法创建一个新的SocialFollowingManager对象,将客户端上下文作为其参数传入。然后,我们可以通过使用getFollowed()方法获得用户关注的所有“演员”。“参与者”实际上就是用户追随的任何东西,可以是用户、文档、站点或标签。当您调用getFollowed()方法时,您需要传入一个数字,该数字对应于您想要返回的参与者。在这个例子中,我们使用 15,这表示所有的参与者。您可以在 http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.social.socialactortypes(v=office.15).aspx 看到完整的值列表。

这个例子中的success方法是迄今为止最复杂的,因为我们需要显示比其他例子更多的数据。首先,我们将获取当前用户的用户名以显示在页面上:

$("#WelcomeMessageUserName").text(userProperties.get_displayName());

userProperties对象有许多方法来检索数据;为了获得用户名,我们可以调用get_displayName()方法。接下来,我们将遍历所有跟随的项目,以构建一个列表来显示给用户:

var followedItems = "Items you are following:<br />";

$.each(following, function( index, value ) {

followedItems += "<a href='" + value.get_uri() + "'>" + value.get_name() + "</a><br />";

});

首先,我们创建一个新变量来保存所有后续的项目。接下来,我们使用 jQuery each循环遍历每个项目。对于每一项,我们调用get_uri()get_name()方法来构造一个链接,这样用户就可以从页面直接跳转到该项。最后,我们用下面一行将所有 HTML 附加到页面上:

$("#UserFollows").append(followedItems);

半铸钢ˌ钢性铸铁(Cast Semi-Steel)

在 Visual Studio 中创建新的 CSS 文件,并将其命名为 JSOMGetSocialData.css 包括以下代码:

#WelcomeMessage {

margin-bottom: 20px;

}

#WelcomeMessageUserName {

font-weight: bold;

}

#UserFollows {

border:dashed 1px #C0C0C0;

width:240px;

padding: 6px;

}

这个 CSS 非常简单,只是为了提供一个简单的样式演示。我们将对用户的欢迎消息应用底部边距,并将用户名用粗体显示。为了强调,下面的项目将用虚线边框包裹起来。

结果

将内容编辑器 Web 部件的内容链接属性设置为 HTML 文件,并保存页面。该页面将向用户显示“欢迎回来”的消息,并以粗体显示他们的姓名。正下方是他们关注的所有项目的列表,显示为超链接,如图 8-23 所示。

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

图 8-23。

Social data being retrieved via JSOM

摘要

在这一章中,我们深入探讨了 JavaScript 对象模型(JSOM ),并研究了如何使用 Etherson 方法来创建自定义 web 部件。我们查看了各种各样的示例:查询列表数据、创建新列表和网站,以及查询用户的社交数据。尽管与本书中的其他章节相比,这是一个很长的章节,但它只是触及了 JSOM 在 SharePoint 中的可能性的皮毛。然而,在完成了这里给出的所有示例之后,您应该对使用 JSOM 以及 HTML、JavaScript 和 CSS 如何在自定义 web 部件中协同工作有了非常深刻的理解。现在,你应该可以开始使用 JSOM 制作你自己的定制解决方案了。在下一章,我们将看很多相同的例子,并学习如何使用 REST API 执行任务。