SharePoint

将 JSLink 与 SharePoint 2013 结合使用

Pritam Baldota

与 SharePoint 用户界面的工作一直是东西开发人员面临的一个挑战。 但是,SharePoint 2013 称为 JSLink 中的新功能减少负载使用 XSLT 的负担,并提供了一种更容易、 更积极的反应的方法,以在客户端上显示自定义字段。 JSLink 是一个通过 JavaScript 文件控件呈现的字段、 项和甚至 Web 部件的属性。

本文将探讨使用 JSLink 的帮助下两个演示方案。 第一种方案将演示如何使用颜色编码的消息以指示完成任务,例如,如中所示图 1

Using a Custom Column for a Task List to Show Status
图 1 使用自定义任务列表的列中显示状态

第二种情况是更为复杂。 它将演示如何实现一个提供为每个图像显示的元数据,并允许在不同的分辨率,下载一个标注,如中所示的图像画廊图 2

Multiple Resolutions of an Image Available for Download
图 2 多分辨率的图像可供下载

此外会深入自定义新建和编辑的窗体字段。 在我开始之前,虽然,我就会带一看 SharePoint 2013 年和 JSLink 将值添加到它在客户端呈现的基本知识。

客户端呈现

客户端呈现是指显示在页上使用在客户端上,如 JavaScript、 HTML 和 CSS 的操作的技术数据。 因为技术在客户端的浏览器中运行,它是更多的响应速度和效率,从而降低 Web 服务器上的负载。 较早版本的 SharePoint 2010 2007年) 使用 XSLT 样式的元素,一般是更加复杂与工作和在性能与 JavaScript 的比较慢。 SharePoint 2013 仍然支持 XSLT,但仍是自定义结果在客户端上的两个附加技术 — — 显示模板,定义 SharePoint 2013 搜索 Web 部件呈现结果的方式 (见 bit.ly/1i5fM6k 的详细信息) 和这篇文章的重点,JSLink 的主题。

JSLink 是一个可以与字段、 Web 部件、 列表形式和内容类型一起使用的属性。 通过此属性,您可以添加 JavaScript 文件,开放自定义项的广泛可能性。 您添加的每个 JavaScript 文件是开头一个 SharePoint 令牌,像这样由管道符号 (|) 分隔:~site/style 图书馆 /­mycustom.js|~site/style library/mycustom2.js。 如果 JavaScript 文件不包含任何相关的呈现代码,则应用默认呈现的元素。

SharePoint 提供几个令牌 (静态和动态),可用于构建特定于上下文的 URL。 这里有一些重要的 SharePoint 令牌动态 URL 施工:

  • ~ 网站 — — 指的是当前 Web 站点的 URL。
  • ~ sitecollection — — 指的是父站点集合的当前 Web 站点的 URL。
  • ~ 布局 — — 指的是 _layouts/15 在 Web 应用程序。
  • ~ sitecollectionlayouts — — 指的是布局文件夹中当前站点集合 (如 /sites/mysite/_layouts/15)。
  • ~ sitelayouts — — 指的是布局文件夹中的当前站点 (如网站/mysite/mysubsite/_layouts/15)。

SharePoint 有 URL 建设的多个标记。 若要了解有关 URL 字符串和令牌的详细信息,请参阅在开发中心 bit.ly/1lpYuAP

使用 JSLink 客户端呈现具有数目的 XSL/XSLT 的优势。 首先,它使用 JavaScript,大多数 Web 开发者已经是舒适。 XSLT 是更为复杂的开发和调试,因此,JSLink 可以减少开发时间不损失精度。

呈现上使用 JavaScript、 HTML 和 CSS 的客户端视图可以避免不必要的负载在服务器上,提高了总体性能和减少页面响应时间。 客户端处理使 UI 响应度很高。

此外,您可以自定义视图中使用 JSLink 的全部或部分。 例如,如果您想要自定义只是一个特定的字段,您可以定制为该字段只 ; 呈现逻辑 将使用默认的逻辑呈现视图的其余部分。 通过 JSLink,你可以使用任何有效的 JavaScript,包括外部插件 jQuery,如与 HTML 和 CSS 的组合。

当然,每一项技术有一些缺点,JSLink 也是如此。 例如,如果用户有被阻止在他的浏览器的 JavaScript,JSLink 将不会工作。 服务器端呈现与 XSLT 仍将显示相同的体验,但是性能可能会受到影响。

如果用户的浏览器或系统是旧的或动力不足 (因为它可能要花更多的时间来执行该脚本,也可能受到影响的性能。

最后,爬网程序不太可能理解 AJAX/JavaScript ; 生成的动态内容 他们需要用 HTML 呈现的静态数据。 所以,如果你有一个面向公众的网站,JSLink 可能不是您的最佳选择。

可以以多种方式使用服务器对象模型、 Windows PowerShell、 Element.xml 通过功能、 Web 部件属性窗口中和客户端对象模型设置的 JSLink JavaScript 文件引用。 下面是一些示例代码,每种方法。

服务器对象模型:若要设置 JSLink 属性的说,列表窗体,您访问使用的列表窗体集合的 SPForm 对象,然后将 JSLink 属性设置为 SPForm 对象:

SPWeb web = SPContext.Current.Web;
SPList list = web.Lists.TryGetList("MyTasks");
if (null != list)
{
  SPForm newForm = list.Forms[PAGETYPE.PAGE_NEWFORM];
  if (null != newForm)
  {
    newForm.JSLink = "~/mycustom.js";
  }
}

Windows PowerShell:若要设置的 JSLink 属性,例如,自定义字段的列表,你访问字段对象使用此列表中的字段集合,然后将 JSLink 属性设置为该字段对象:

$web = Get-SPWeb
$field = $web.Fields["MyCustomField"]
$field.JSLink = "~/layouts/mycustom.js"
$field.Update()
$web.Dispose()

Element.xml 文件:要设置 JSLink 属性的自定义字段的列表,您将某一字段节点添加到 Element.xml 文件:

<Field ID="{eb3eed37-961b-41bd-b11c-865c16e47071}"
Name="MyCustomField" DisplayName="Custom Columns"
Type="Text" Required="FALSE" Group="JSLink Demo"
JSLink="~site/style library/JSLinkDemo/jquery-1.10.2.min.js|
~site/style library/JSLinkDemo/customview.js">
</Field>

请注意通过使用管道符号,您可以添加多个 JavaScript 文件。

Web 部件属性对话框中:若要设置 JSLink 属性的 Web 部件,您可以修改其属性。 转到 Web 部件 |编辑属性 |杂项和设置 JSLink 属性。

客户端对象模型 (CSOM):您可以设置字段使用 CSOM 的 JSLink。 请注意不能直接更新通过 JavaScript 的网站列属性,您需要更新它使用关联列表字段。 如果您尝试更新站点列级别,您将收到此错误:

此功能不可用于不与列表相关联的字段...

 

此代码演示如何正确地更新通过 JavaScript CSOM 列表中的字段的 JSLink 属性:

fieldCollection = taskList.get_fields();
this.oneField = fieldCollection.getByInternalNameOrTitle("MyCustomField");
this.oneField.set_description("MyNewFieldDescription");
this.oneField.update();

此示例的详细信息,请参阅 MSDN 文档在 bit.ly/1i9rlZR

为了使用 JSLink,您需要重写此方法的自定义 JavaScript 文件中:

SPClientTemplates.TemplateManager.RegisterTemplateOverrides()

此方法需要一个模板对象传递给它。 若要定义的模板对象,必须指定一个属性和为每个视图 (如查看、 添加和编辑) 的 render 方法。

注册方法的模板对象具有属性,如标题、 正文、 页脚、 OnPreRender、 OnPostRender、 组、 项目和字段,可以利用来重写默认的视图的呈现逻辑。 例如,若要修改视图、 显示、 编辑和新的自定义字段,您可以提供模板对象的字段属性的以下信息:

siteCtx.Templates.Fields = {
  // MyCustomField is the Name of our field
  'MyCustomField': {
  'View': customView,
  'DisplayForm': customDisplayForm,
  'EditForm': customNew,
  'NewForm': customEdit
  }
};

在此代码中,如自定义视图和 customDisplayForm,引用的方法包含此字段的实际呈现逻辑。

最后,调用 RegisterTemplateOverrides 方法的 TemplateManager 要应用自定义的视图,就像这样:

 

// Register the template to render custom field
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(siteCtx);

此方法会照顾余生的基于您的自定义逻辑视图的呈现。

请记住当您使用同一页上的多个实例的列表视图 Web 部件并将 JSLink 应用于其中一个实例,所有其他列表的布局查看 Web 部件更改还,因为 SharePoint 内部使用共同呈现逻辑。 若要避免此问题,您需要确保的 BaseViewID 值不会与现有 ViewIDs 发生冲突,所以重写,例如,环磷酰胺之前更改上下文的 BaseViewID 属性。BaseViewID = 1000年。

现在我送你两个示范方案通过。

方案 1:显示颜色编码的任务完成状态

这种情况下显示任务完成状态使用颜色编码为一个任务列表 — — 红色为未完成的任务和绿色为已完成的任务。

在示例中,我将自定义的视图模板的自定义字段,如下所示:

// View Page custom rendering
function customView(ctx) {
if (ctx != null && ctx.CurrentItem != null) {
  var percentCompete = parseInt(ctx.CurrentItem.PercentComplete);
  if (percentCompete != 100) {
    return "<span style='color:red'>Incomplete Task</span>";
  }
  else {
    return "<span style='color:green'>Task Completed</span>";
  }
}
}

自定义视图方法接收当前渲染上下文作为输入参数从 SharePoint 的内部。 此输入的上下文有很多其他与相关的属性列表、 视图、 当前项目等等。

上下文的 currentItem 属性使访问列表中的当前行项目。 通过此属性,您可以访问所有字段列表中的可用。 请注意是否该字段不是所选视图中的可用,你将得到错误,访问该字段值时。

首先,打开 Visual Studio 2013 并选择一个 SharePoint 2013 空项目。

步骤 1:从添加新项菜单中,将一个网站栏添加到空项目。 若要创建网站列,添加字段信息在 Element.xml 文件中,如中所示图 3。 正如您所看到的 JSLink 属性引用两个 JavaScript 文件:JQuery 库和自定义视图 JavaScript 文件从样式库。 请注意从左到右 (依赖文件应首先引用) 应保持文件的层次结构。

引用的 JavaScript 文件图 3

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/"> 
  <Field
    ID="{eb3eed37-961b-41bd-b11c-865c16e47071}"
    Name="MyCustomField"
    DisplayName="Custom Columns"
    Type="Text"
    Required="FALSE"
    Group="JSLink Demo"
    JSLink="~site/style library/JSLinkDemo/jquery-1.10.2.min.js|
            ~site/style library/JSLinkDemo/customview.js">
  </Field>
 
</Elements>

步骤 2:添加另一个新项目,一个脚本模块,以存储自定义 JavaScript 和其他资源文件。

步骤 3:JQuery 库添加到脚本模块。 创建一个新的 JavaScript 文件,称为 CustomView.js。

步骤 4:重命名默认的功能从功能 1 到 JSLinkDemo,或创建一个新功能,包括站点列和脚本模块。 将范围设置为网站,因为它是将部署的网站栏。

步骤 5:部署解决方案。 您部署解决方案后,您就会看到通过转到网站设置添加到站点的列的列 |网站栏。

步骤 6:创建任务列表,由从网站内容页中添加一个应用程序调用 MyTasks。

步骤 7:将自定义的列添加到 MyTasks 列表中,从功能区上列表设置菜单。

步骤 8:添加自定义的列,如使用步骤 1 到 5 的从现有网站栏列表设置页上单击添加创建的。 筛选使用 JSLink 演示的组,选择自定义列和将它添加到列表中。

这样就完成了第一种方案,其中显示了任务的完成状态的执行情况。 正如你可以看到在图 1,自定义状态会显示为任务已完成在绿色或不完整任务中红。

方案 2:创建自定义图像库与标注

在这种情况下我会自定义要在自定义表格格式,带有标注要下载多个分辨率的图像中显示的内置的图像画廊呈现。

为此,我自定义的项、 页眉和页脚模板字段的属性。 下面的代码设置的第一步:

(function () {
  var overrideContext = {};
  overrideContext.ListTemplateType = 109;
  overrideContext.Templates = {};
  overrideContext.Templates.Item = customItem;
  SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext);
})();
 
function customItem() {
  return "ItemRow";
}

我已经将 ListTemplateType 设置为 109,SharePoint PictureLibrary 作为预定义了。 (你会发现所有预定义的列表模板类型在 SharePoint 2013 年 bit.ly/1qE8UiY.)此代码将呈现行与从 customItem 方法返回的文本。

现在,我会将静态文本替换图像 (标题、 URL 和其他字段),开始呈现图像的实际属性。 若要替换默认新图片链接和标题的列,就会自定义的页眉和页脚的属性来设置一些 HTML 文本:

overrideContext.Templates.Header = "<b>Custom Image Gallery View</b>";
overrideContext.Templates.Footer = "<b>Custom Footer</b>";
function customItem() {
  return "<br /><img src='" + ctx.CurrentItem.FileRef +
  "' width='190' height='190' />;
}

我想要以表格格式显示图像。 要这样做,有的布局在 customItem 方法中添加一些 CSS 和 HTML。 首先,我将空 div 容器添加到页眉模板,将稍后用于保存项目和页脚呈现的实际数据。 在范围内的项目呈现创建动态 HTML 并将它存储在一个全局变量。 在页脚呈现模板中,我将动态数据分配到 div 容器。 图 4 显示的完整的代码来呈现一个表格格式图像廊。

图 4 中以表格的形式显示的图像

function customItem(ctx) {
  // Grid contains 4
  if (ctx.CurrentItemIdx % 4 == 0) {
    // Start new row
    tableData+= "<div style='clear:both'></div>"
  }
 
  tableData += "<div style='margin:5px;border:1px solid #666;float:left;"+
  "width:100px;height:100px' onmouseover=\""+
  "ShowCallout(this,'" + ctx.CurrentItem.Title + "','" +
  ctx.CurrentItem.FileDirRef + "','" + ctx.CurrentItem.FileLeafRef
  + "');\"><img src='" + ctx.CurrentItem.FileRef +
  "' width='100' height='100' /></div>";
 
return "";
}
 
// Custom Footer Method
function customFooter(ctx) {
  // Append Dynamic-generated data to container div
  $("#customImageGalleryContainer").html(tableData);
  return "";
}

现在我想在鼠标移到每个图像上显示标注和显示附加元数据 (如标题、 简介,等等,同时为下载不同的图像分辨率。 SharePoint 2013 使用 CalloutManager 全局对象提供一个标注框架,通过一个 callout.js JavaScript 文件显示的上下文信息。 我会利用这一框架以显示默认标注。 首先,创建一个自定义的方法调用 ShowCallout 来确定是否有任何现有的开放标注 ; 如果有,我将关闭它们使用来自 CalloutManager 的默认 closeAll 方法:

function ShowCallout(sender, itemId, title, brief, directory, filename) {
  CalloutManager.closeAll();
}

在着手实施之前, 您需要了解如何获得不同分辨率的图像。 在 SharePoint 2013 年,在默认情况下图像中两个不同的大小时创建它上载到图片库。 例如,如果您上载到库路径/imageLibraryName/sample.png,SharePoint 会自动创建一个缩略图和 Web 大小的图像:/imageLibrary­Name/_t/Sample_png.jpg 和 /imageLibraryName/_w/­Sample_png.jpg。 在这些 Url,_t 表示缩略图和 _w 表示 Web 和文件扩展名获取追加到文件名以前缀下划线 (_) 分隔符。

ShowCallout 函数使用这些 Url 为原始图像,以及图像的不同的决议,并将它们存储在不同的变量,如下所示 (文件名和目录是 ShowCallout 参数):

var fname = filename.replace(".", "_");
var thumbnail = directory + "/_t/" + fname + ".jpg";
var medium = directory + "/_w/" + fname + ".jpg";
var full = directory + "/" + filename;

对于这种情况下我使用 CalloutManager createNewIfNecessary 方法,只有在目标发射点有没有标注创建标注。 如果有一个标注,则该方法将返回现有的对象引用。 (阅读更多关于 CalloutManager,访问 bit.ly/1kXH7uU.)图 5 显示的完整代码,和图 6 显示得到的输出。

图 5 更新的 ShowCallout 函数

function ShowCallout(sender, itemId, title, brief, directory, filename) {
  // Close fists all callouts if opened
  CalloutManager.closeAll();
  var fname = filename.replace(".", "_");
  var thumbnail = directory + "/_t/" + fname + ".jpg";
  var medium = directory + "/_w/" + fname + ".jpg";
  var full = directory + "/" + filename;
  var calloutContent = "<img src='" + medium + "' width='50%'
    height='50%' /><br/>" +
  brief + " <a href='" + directory + "/Forms/DispForm.aspx?ID=" +
  itemId + "'>View Image</a><br />" +
  "<a href='" + thumbnail + "' target='_blank'>
    Thumbnail</a>  |  " +
  "<a href='" + medium + "' target='_blank'>
    Web Size</a>  |  " +
  "<a href='" + full + "' target='_blank'>Original Size</a>";
 
  var calloutRef = CalloutManager.createNewIfNecessary({
    ID: 'call_' + itemId, launchPoint: sender,
    beakOrientation: 'leftRight', title: title,
    content: calloutContent,
    contentWidth: 610
  });
 
  calloutRef.open();
}

Custom Image Gallery with Callout Showing Metadata
图 6 自定义图像画廊与标注显示的元数据

若要应用自定义呈现,创建网站页并添加图像库列表视图 Web 部件。 转到编辑 web 部件属性对话框中,将 JSLink 属性设置为 ~/site/Style Library/JSLinkDemo/jquery-1.10.2.min.js|~/site/Style 自定义库/JSLinkDemo/­ImageGallery.js。 单击应用,并保存页面。 后刷新页面,您会看到在所示的画廊图 6

可以自定义新和编辑窗体字段用类似的方法,虽然一些变异。 在这里你需要考虑作为输入验证,这种事情存储输入字段中的数据到列表项显示存储的数据从一个列表项中输入的字段等等。

下一步,我就会看看一个复杂的、 多列的自定义字段方案的执行细节中所示图 7

Multi-Column Custom Fields of a List Using JSLink
图 7 多列的列表使用 JSLink 的自定义字段

步骤 1:使用 Element.xml 的文件,创建注释 (下网站列,要说,1000 (或不管适合您的需要) 的设置 NumLines 属性的文本的自定义字段。 此自定义的字段将覆盖在新建和编辑的窗体上呈现。

siteCtx.Templates.Fields = {
  "MyComplexField": {
  'EditForm': customComplexNewOrEdit,
  'NewForm': customComplexNewOrEdit
}
};

对于新查看和编辑都使用相同的 customComplexNewOrEdit 方法。

步骤 2:设置窗体上下文,是需要设置的验证程序,从自定义视图中读取值,并将其保存回列表。 若要设置窗体上下文你使用 SPClientTemplates.Utility.GetFormContextForCurrentField 方法。 此方法接受作为参数,它由 SharePoint 内部提供呈现的上下文。 下面是一些示例代码显示新或编辑自定义呈现器方法:

 

function customComplexNewOrEdit(ctx) {
  if (ctx == null || ctx.CurrentFieldValue == null)
  return '';
 
  var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(ctx);
  if (formCtx == null || formCtx.fieldSchema == null)
    return '';
}

步骤 3:在窗体上下文后,您需要启用验证、 获取字段的值,并在适当的字段中保存的值上从 JSLink 生成的自定义视图的当前窗体中注册回调处理程序。 每次用户单击保存按钮在列表表单上,SharePoint 内部调用回调处理程序附加到使用 formCtx.registerGetValueCallback (filedName,回调) 的字段。 此回调处理程序读取值从字段保存到列表项之前:

formCtx.registerGetValueCallback(formCtx.fieldName, function () {
  // Read value from this callback and assign to the field before save
  return "";
});

这是一个空的回调处理程序。 你有自定义的代码以便从选定的控件在窗体上读取的值和返回值的字符串表示形式。

步骤 4:若要添加验证程序,您需要首先创建要在其中注册的各个字段的验证程序的验证器容器。 这样做使用的 SPClientForms.ClientValidation.ValidatorSet 对象。 我可以使用验证程序容器的 RegisterValidator 方法来注册多个验证程序。

您需要注册错误回调处理程序,以及要显示的错误。 要这样做,我会使用 registerValidationErrorCallback 方法的窗体上下文。 此方法需要两个参数,HTML 容器元素 (在此示例中的 div) 和 errorResult,ID,则返回从 SharePoint 内部基于验证失败。 错误消息将追加到为此方法提供的容器元素。 我需要在我的示例添加一个必填的字段验证器和用于验证的完整代码所示图 8

图 8 验证代码

var validatorContainer = new SPClientForms.ClientValidation.ValidatorSet();
if (formCtx.fieldSchema.Required) {
  validatorContainer.RegisterValidator(
  new SPClientForms.ClientValidation.RequiredValidator());
}
 
if (validatorContainer._registeredValidators.length > 0) {
  formCtx.registerClientValidator(
  formCtx.fieldName, validatorContainer);
}
 
formCtx.registerValidationErrorCallback(
  formCtx.fieldName, function (errorResult) {
    SPFormControl_AppendValidationErrorMessage(
    errorContainer, errorResult);
});

步骤 5:您需要添加自定义的 HTML 控件来表示在新的字段或编辑页。 我会有一个文本框、 一个下拉列表与另一个列表中的动态值和一个下拉列表中使用静态值。 我会创建一个表,向表中添加这些控件并返回 HTML 作为输出从自定义添加/编辑方法。

为了动态地加载数据,我使用其他 API 读取另一个列表中的数据,并使用它来填充该列表中的标题。 若要了解有关在 SharePoint 中的其余部分 API 的详细信息,请参阅 bit.ly/1cVNaqA

图 9 显示动态呈现的输入的控件的代码。

图 9 呈现的输入控件动态

// Render input fields
var inputFields = "<table>";
...
inputFields += "</table>";
 
// Get List data from REST API
$.ajax({
...
success: function (data) {
  // Add options to the dynamic dropdown list
},
error: function (data) {
  // Error handler
}
});
 
 
return inputFields;

步骤 6:要将一个多字段的值保存到列表中,我将所有字段的值放入一个字符串使用字符串的分隔符,并创建自定义格式 (如 (fieldname:value)(fieldname:value),一种的键-值对。 我会做 registerGetValueCallback 的字符串建设。

步骤 7:若要编辑窗体中显示的现有值,解析作为一个键-值对,保存并将值分配给各自的输入控件存储的字符串。 这是使用相同的自定义呈现方法构建自定义 HTML 时完成的。

总结

您可以调试使用基于浏览器的开发人员工具如互联网浏览器开发人员工具,Firebug 之类的 JSLink。 如果你在 JavaScript 中放置一个断点后它呈现在客户端,您可以调试就像 C#.NET 代码 JavaScript。 当您访问的视图方法中的上下文时,您可以对通过它你可以看到当前项的每个字段的值的当前项的引用。 可以使用互联网资源管理器开发人员工具控制台窗口来访问当前的对象的任何属性。

JSLink 提供了自定义任何 SharePoint 视图中使用一个纯净的客户端脚本,而无需编写一行的服务器端代码的简单方法。 您可以使用任何基于 JavaScript 插件与 JSLink。 下载示例演示项目在 msdn.microsoft.com/magazine/msdnmag0614

Pritam Baldota 是一个 SharePoint 顾问在 Microsoft 服务全球交付与超过九年的行业经验。在他的休闲时间他在博客 pritambaldota.com。联系到他在 pritam@pritambaldota.com

衷心感谢以下 Microsoft 技术专家对本文的审阅: 桑杰罗拉、 Subhajit Chatterjee 和帕雷什 Moradiya
桑杰罗拉 — — 桑贾伊是在 Microsoft 服务全球交付专业发展资源管理器。

Subhajit 查特吉是与 Microsoft 服务全球交付具有 12 年以上的行业经验的高级顾问。 他已执行许多交钥匙和复杂订婚在 GD。

帕雷什 Moradiya 在软件行业拥有 11 + 多年的经验。 他目前正在自过去 5 年以来作为与微软公司的顾问。 他是在 SharePoint Web 内容管理和 SharePoint 社会的中小企业。