Project Server 2013 JavaScript 对象模型入门

在 Project Server 2013 中,JavaScript 对象模型可用于Project Online、移动和本地开发。 本主题简要概述了 JavaScript 对象模型,然后介绍如何创建应用程序页,以便使用 JavaScript 对象模型检索和循环访问项目。

使用 Project Server JavaScript 对象模型

使用 JavaScript 对象模型是创建运行客户端 ((而不是需要远程运行) 的托管客户端代码)的应用的好方法。 应用可以使用 JavaScript 对象模型通过向服务器发送异步调用来检索或更改对象。 使用 JavaScript 对象模型的应用通常部署为自定义 SharePoint 外接程序、应用程序页面和 Web 部件。 有关详细信息,请参阅 SharePoint 2013 中的主机 Web、外接程序 Web 和 SharePoint 组件中的“可位于 SharePoint 应用程序中的 SharePoint 组件类型”。

JavaScript 对象模型实现了 Project Server 2013 的main功能,但 JavaScript 对象模型和服务器对象模型没有一对一奇偶校验。 JavaScript 对象模型的入口点是 ProjectContext 对象,它表示 Project Server 2013 的客户端上下文,并提供对服务器内容和功能的访问权限。 Project Server 2013 的 JavaScript 对象模型在 PS.js 文件中定义,该文件位于应用程序服务器上的默认路径 %ProgramFiles%\Common Files\Microsoft Shared\Web Server Extensions\15\TEMPLATE\LAYOUTS 中。 Project Server 2013 还会在同一位置安装 PS.Debug.js 文件。 PS.Debug.js 是 PS.js 的未缩小版本,它提供了 IntelliSense 信息。

JavaScript 对象模型允许 Forms 身份验证,并且所有请求都以当前用户的身份进行身份验证。 有关设计自定义应用和解决方案的安全性和其他注意事项的详细信息,请参阅 SharePoint 2013 中的身份验证、授权和安全性SharePoint 外接程序体系结构和开发环境的重要方面,以及 SharePoint 外接程序与 SharePoint 解决方案的比较

注意

若要从 SharePoint 站点远程访问数据,SharePoint 2013 提供了一个跨域库,可用于进行客户端跨域调用。 有关详细信息,请参阅 使用跨域库从加载项访问 SharePoint 2013 数据

用于 Project Server 2013 的 JavaScript 对象模型的许多概念和过程与相关客户端对象模型中的概念和过程类似。 有关 Project Server 2013 托管客户端对象模型的详细信息,请参阅 Microsoft.ProjectServer.Client。 有关 SharePoint 2013JavaScript 对象模型和托管客户端对象模型的详细信息,请参阅 在 SharePoint 2013 中使用 JavaScript 库代码完成基本操作 和使用 SharePoint 2013 客户端库代码完成基本操作

演练:创建可检索和循环访问各个项目的应用程序页

了解如何创建可显示网站中每个已发布项目的 ID、名称和创建日期的应用程序页。

创建可检索和循环访问各个项目的应用程序的先决条件

若要开发本主题中描述的应用程序页,您必须安装和配置以下产品:

  • SharePoint Server 2013
  • 具有至少一个已发布项目的 Project Server 2013
  • Visual Studio 2012
  • Visual Studio 2012 Office 开发人员工具

您还必须有权将扩展部署到 SharePoint Server 2013 并检索项目。

注意

这些说明假定你在运行 Project Server 2013 的计算机上进行开发。

在 Visual Studio 2012 中创建应用程序页

以下步骤创建了一个 SharePoint 项目和一个包含表和标签的应用程序页。 表显示了有关项目的信息,标签显示了错误消息。

  1. 在运行 Project Server 2013 的计算机上,以管理员身份运行 Visual Studio 2012。

  2. 创建一个空的 SharePoint 2013 项目,如下所示:

    1. 在"新建项目"对话框中,从对话框顶部的下拉列表中选择".NET Framework 4.5"。

    2. 在模板类别列表中,选择“Office SharePoint”类别,然后选择“SharePoint 2013 项目”模板。

    3. 将项目命名为 GetProjectsJSOM,然后选择“ 确定” 按钮。

    4. 在“SharePoint 自定义向导”对话框中,选择“部署为场解决方案”,然后选择“确定”按钮。

  3. 在 解决方案资源管理器 中,编辑 ProjectsJSOM 项目的“网站 URL”属性的值,以匹配 Project Web App 实例 (的 URL,例如,) https://ServerName/PWA

  4. 打开“GetProjectsJSOM”项目的快捷菜单,然后添加 SharePoint“Layouts”映射文件夹。

  5. “布局” 文件夹中,打开 GetProjectsJSOM 文件夹的快捷菜单,然后添加名为 ProjectsList.aspx 的新 SharePoint 应用程序页。

    注意

    此示例不使用 Visual Studio 2012 为应用程序页创建的代码隐藏文件。

  6. 打开 ProjectsList.aspx 页的快捷菜单,然后选择“设置为启动项”

  7. ProjectsList.aspx 页的标记中,在“主要”asp:Content 标记中定义一个表和一个消息占位符,如下所示。

    <table width="100%" id="tblProjects">
        <tr id="headerRow">
            <th width="25%" align="left">Project name</th>
            <th width="25%" align="left">Created date</th>
            <th width="50%" align="left">Project ID</th>
        </tr>
    </table>
    <div id="divMessage">
                <span id="spanMessage" style="color: #FF0000;"></span>
    </div>
    

检索项目集合

可通过以下步骤检索和初始化项目集合。

  1. 在结束 div 标记的后面,添加一个引用 PS.js 文件的 SharePoint:ScriptLink 标记,如下所示。

     <SharePoint:ScriptLink name="PS.js" runat="server" ondemand="false" localizable="false" loadafterui="true" />
    
  2. SharePoint:ScriptLink 标记的下方,添加 script 标记,如下所示。

     <script type="text/javascript">
         // Paste the remaining code snippets here, in the order that they are presented.
     </script>
    
  3. 声明一个全局变量以存储项目集合,如下所示。

    var projects;
    
  4. 调用 SP.SOD.executeOrDelayUntilScriptLoaded 方法以确保 PS.js 文件在您的自定义代码运行之前加载。

    SP.SOD.executeOrDelayUntilScriptLoaded(GetProjects, "PS.js");
    
  5. 添加一个将连接到当前上下文并检索项目集合的函数,如下所示。

     function GetProjects() {
         // Initialize the current client context.
         var projContext = PS.ProjectContext.get_current();
         // Get the projects collection.
         projects = projContext.get_projects();
         // Register the request that you want to run on the server.
         // This call includes an optional "Include" parameter to request only the
         // Name, CreatedDate, and Id properties of the projects in the collection.
         projContext.load(projects, 'Include(Name, CreatedDate, Id)');
         // Run the request on the server.
         projContext.executeQueryAsync(onQuerySucceeded, onQueryFailed);
     }
    

    通过上下文检索的某些客户端对象在初始化之前不包含任何数据;也就是说,在初始化对象之前,无法访问对象的属性值。 此外,对于 ValueObject 类型的属性,必须先显式请求 属性,然后才能访问其值。 (如果在初始化属性之前尝试访问该属性,则会收到 PropertyOrFieldNotInitializedException exception.)

    若要初始化对象,您可以依次调用 load 方法(或 loadQuery 方法)和 executeQueryAsync 方法。

    • 调用 load 函数或 loadQuery 函数将注册要在服务器上运行的请求。 您将传入一个表示要检索的对象的参数。 如果您使用的是 ValueObject 属性,则还要在参数中请求该属性。

    • 调用 executeQueryAsync 函数会通过异步方式向服务器发送查询请求。 您将传入一个成功回调函数和一个失败回调函数,在收到服务器响应时将调用它们。

    为了减少网络流量,在您调用 load 函数时仅请求要使用的属性。 此外,如果您使用了多个对象,则在调用 executeQueryAsync 函数之前,将针对 load 函数的多个调用进行分组(如果可能)。

循环访问项目集合

可通过以下步骤循环访问项目集合(如果服务器调用成功)或呈现错误消息(如果调用失败)。

  1. 添加一个可循环访问项目集合的成功回调函数,如下所示。

     function onQuerySucceeded(sender, args) {
         // Get the enumerator and iterate through the collection.
         var projectEnumerator = projects.getEnumerator();
         while (projectEnumerator.moveNext()) {
             var project = projectEnumerator.get_current();
             // Create the row for the project's information.
             var row = tblProjects.insertRow();
             // Insert cells for the Id, Name, and CreatedDate properties.
             row.insertCell().innerText = project.get_name();
             row.insertCell().innerText = project.get_createdDate();
             row.insertCell().innerText = project.get_id();
         }
     }
    
  2. 添加一个可呈现错误消息的失败回调函数,如下所示。

    function onQueryFailed(sender, args) {
        $get("spanMessage").innerText = 'Request failed: ' + args.get_message();
    }
    
  3. 若要测试应用程序页,请在菜单栏上选择“调试”和“启动调试”。 如果系统提示您修改 web.config 文件,请选择“确定”

完整的代码示例

以下是 ProjectsList.aspx 文件中的完整代码。

<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ProjectsList.aspx.cs" Inherits="GetProjectsJSOM.Layouts.GetProjectsJSOM.ProjectsList" DynamicMasterPageFile="~masterurl/default.master" %>
<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
</asp:Content>
<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
    <table width="100%" id="tblProjects">
    <tr id="headerRow">
        <th width="25%" align="left">Project name</th>
        <th width="25%" align="left">Created date</th>
        <th width="50%" align="left">Project ID</th>
    </tr>
</table>
<div id="divMessage">
        <span id="spanMessage" style="color: #FF0000;"></span>
</div>
<SharePoint:ScriptLink name="PS.js" runat="server" ondemand="false" localizable="false" loadafterui="true" />
<script type="text/javascript">
    // Declare a variable to store the published projects that exist
    // in the current context.
    var projects;
    // Ensure that the PS.js file is loaded before your custom code runs.
    SP.SOD.executeOrDelayUntilScriptLoaded(GetProjects, "PS.js");
    // Get the projects collection.
    function GetProjects() {
        // Initialize the current client context.
        var projContext = PS.ProjectContext.get_current();
        // Get the projects collection.
        projects = projContext.get_projects();
        // Register the request that you want to run on the server.
        // This call includes an optional "Include" parameter to request only the
        // Name, CreatedDate, and Id properties of the projects in the collection.
        projContext.load(projects, 'Include(Name, CreatedDate, Id)');
        // Run the request on the server.
        projContext.executeQueryAsync(onQuerySucceeded, onQueryFailed);
    }
    function onQuerySucceeded(sender, args) {
        // Get the enumerator and iterate through the collection.
        var projectEnumerator = projects.getEnumerator();
        while (projectEnumerator.moveNext()) {
            var project = projectEnumerator.get_current();
            // Create the row for the project's information.
            var row = tblProjects.insertRow();
            // Insert cells for the Id, Name, and CreatedDate properties.
            row.insertCell().innerText = project.get_name();
            row.insertCell().innerText = project.get_createdDate();
            row.insertCell().innerText = project.get_id();
        }
    }
    function onQueryFailed(sender, args) {
        $get("spanMessage").innerText = 'Request failed: ' + args.get_message();
    }
</script>
</asp:Content>
<asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
Application Page
</asp:Content>
<asp:Content ID="PageTitleInTitleArea" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server" >
My Application Page
</asp:Content>

另请参阅