TypeScriptを使用してSharePoint 2013アプリケーションを開発する

前回 、アプリケーション開発にTypeScriptを使用する利点について説明しました。



この投稿では、TypeScriptがSharePoint 2013用のアプリケーションの開発にどのように役立つかを示します。SharePoint2013では、JavaScriptクライアント開発機能が改善されました。 これは、クライアントで使用可能なAPIだけでなく、アプリケーションと開発者ツールの配信および展開メカニズムにも適用されます。 さらに、SharePoint 2013自体の多くの機能が実装されており、JavaScriptを使用してカスタマイズできます。





SharePoint 2013は、クライアント側で使用する2種類のAPI、クライアント側オブジェクトモデル(CSOM)とREST APIを提供します。 REST APIを使用すると、REST(OData)Webサービスを使用してサーバー上のオブジェクトを操作できます。 CSOMは、SharePointサーバーオブジェクトモデルと意味的に同等のクラスのコレクションです。 CSOMは、JavaScript(JSOM-JavaScript Object Modelとも呼ばれます)と.NETの両方で使用できます。 ただし、JavaScriptでは、.NETとは異なり、メタデータと入力は使用できません。 この記事では、JSOMの使用について正確に調べます。



TypeScriptを使用すると、JSOMの型を記述し、アプリケーションの開発時に静的型チェックとインテリセンスを使用できます。 残念ながら、SharePoint 2013の既製のタイプ定義は公開されていません。



私とAndrei MarkeevがCodePlexプロジェクトを作成しました。このプロジェクトでは、SharePoint 2013のタイプ定義と多数のサンプルTypeScriptアプリケーションを作成しました。プロジェクトリンクはhttp://sptypescript.codeplex.com/です。



応用例

たとえば、職場での時間を追跡できるアプリケーションを作成します。







準備する


最初に必要なもの:





プロジェクトをビルドするときにTypeScriptをコンパイルするには、次の要素を.csprojファイルに追加する必要があります。



<PropertyGroup> <TypeScriptTarget>ES3</TypeScriptTarget> <TypeScriptIncludeComments>true</TypeScriptIncludeComments> <TypeScriptSourceMap>true</TypeScriptSourceMap> </PropertyGroup> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" />
      
      







ライブラリと定義


ビジュアルインターフェイスは、koLite拡張子を持つknockoutjsライブラリを使用して作成されます。



プロジェクトでこれらのライブラリを使用するには、次のNuGetパッケージを追加する必要があります。





最後の3つのパッケージは、TypeScriptの型を記述する.d.tsファイルです。



TypeScriptでJSOMを操作するには、リンクにあるSharePoint.d.tsファイルをプロジェクトに追加する必要があります。 NuGetパッケージはまもなく利用可能になります。



オンデマンドでスクリプトをダウンロードする

SharePointには、SP.SODクラスに独自のオンデマンドスクリプトローダーがあります。 詳細な説明は、 この投稿にあります。



アプリケーションスクリプトローダーコード:



 ///<reference path="typings/SharePoint.d.ts" /> ///<reference path="typings/jquery/jquery.d.ts" /> ///<reference path="typings/knockout/knockout.d.ts" /> /// <reference path="ViewModel.ts" /> $(() => { SP.SOD.registerSod('ViewModels', _spPageContextInfo.webServerRelativeUrl + '/Scripts/ViewModel.js'); SP.SOD.registerSodDep('ViewModels', 'sp.js'); SP.SOD.executeFunc('ViewModels', null, () => { var vm = new ViewModels.Model(SP.ClientContext.get_current()); ko.applyBindings(vm); }); });
      
      







プレゼンテーションモデル


アプリケーションページのレイアウト:



 <div> <p data-bind="text:message"></p> <button data-bind="text:buttonText, command: checkInOut, visible:isLoaded" style="display:none;"/> </div>
      
      







koLiteプラグインは 、非同期コマンドに使用されます。



モデルコードを表示:



 module ViewModels { export class Model { constructor(public context: SP.ClientContext) { this.isLoaded = ko.observable(false); this.message = ko.observable(''); this.buttonText = ko.observable(''); this.checkInOut = ko.asyncCommand({ canExecute: (isExecuting) => !isExecuting && this.isLoaded(), execute: this.executeCheckInOut }); this.init(); } public message: KnockoutObservableString; public buttonText: KnockoutObservableString; public checkInOut: KoliteCommand; public isLoaded: KnockoutObservableBool; //... } }
      
      







すべてのタイプは.d.tsファイルに記述され、コンパイル時にチェックされます。

JSOMは、実行されると、 SP.ClientContext.executeQueryAsync関数によってサーバーに送信されるコマンドのキューを形成します。 executeQueryAsyncは2つのコールバックを受け入れます。1つ目は成功時に呼び出され、2つ目は失敗時に呼び出されます。 注意、 thisポインターはexecuteQueryAsync関数のコールバック内で損なわれますが、コールバックをラムダとして指定すると、TSはthisポインターを格納するコードを慎重に生成します。



 private init() { this.list = this.context.get_web().get_lists().getByTitle('Log'); var items = this.list.getItems(SP.CamlQuery.createAllItemsQuery()); this.context.load(items); this.context.executeQueryAsync( () => { this.processItems(items); this.setData(); this.isLoaded(true); }, (sender, args) => alert(args.get_message())); };
      
      





JSOMの要素セットのクエリは、配列を返しませんが、IEnumerableインターフェイスを実装するオブジェクトのコレクションを返しますが、配列はオブジェクト内にあります。 これは、ほとんどのクライアントオブジェクトモデルがサーバーオブジェクトモデルから生成され、すべてのコレクションがトラバーサルのために特別なパターンを必要とするという事実によるものです。 IEnumerableコレクションを処理するための.NETコードに完全に準拠しています。



クエリ結果の処理:



 private processItems(items: SP.ListItemCollection) { this.hoursSubmitted = 0; var enumerator = items.getEnumerator(); while (enumerator.moveNext()) { var item = <SP.ListItem>enumerator.get_current(); var author = <SP.FieldUserValue>item.get_item('Author'); //Filter by current user if (author.get_lookupId() == _spPageContextInfo.userId) { var dateCompleted = item.get_item('DateCompleted'); if (dateCompleted) { this.hoursSubmitted += item.get_item('DurationInHours'); } else { this.curentItem = item; } } } }
      
      





上記のコードは、型キャストの実行方法も示しています。 TypeScriptはすべての型キャスト操作を信頼するため、それらが正しいことを確認する必要があります。



コマンド処理

モデルの現在の状態に応じて、チェックインまたはチェックアウトが実行されます。



 private executeCheckInOut(complete: () => void ) { if (this.curentItem) { this.checkOut(complete); } else { this.checkIn(complete); } };
      
      







チェックイン操作では、完了時間を指定せずに、SharePointリストに新しいアイテムを作成します。



 private checkIn(complete: () => void ) { var item = this.list.addItem(new SP.ListItemCreationInformation()); item.set_item('StartDate', new Date()); item.update(); this.context.executeQueryAsync( () => { this.curentItem = item; this.setData(); complete(); }, (sender, args) => { alert(args.get_message()); complete(); }); }
      
      







反対の操作であるチェックアウトは、完了時間と期間を時間単位で入力します。



 private checkOut(complete: () => void ) { var startedDate = <Date>this.curentItem.get_item('StartDate'); var dateCompleted = new Date(); var hours = (dateCompleted.getTime() - startedDate.getTime()) / (1000 * 60 * 60); this.curentItem.set_item('DateCompleted', dateCompleted); this.curentItem.set_item('DurationInHours', hours); this.curentItem.update(); this.context.executeQueryAsync( () => { this.curentItem = null; this.hoursSubmitted += hours; this.setData(); complete(); }, (sender, args) => { alert(args.get_message()); complete(); }); }
      
      





どちらの場合も、同じ「パターン」が使用されます。 まず、サーバーに送信するためのコマンドのパッケージが生成され、アプリケーションが正常に完了すると、変更がモデルに反映されます。



おわりに



リンクから完全なサンプルコードをダウンロードできます。 また、プロジェクトコードとSharePointのTypeScript定義の使用例( ソースコード )を確認することをお勧めします。多くの興味深いことが見つかります。



ちなみに、サンプルコード自体はSharePoint 2010で機能しますが、別のプロジェクトを作成し、ソリューションアーティファクトを別の方法で展開して、すべてが連携して動作するようにする必要があります。



そして次回は、SharePoint 2013で、またTypeScriptでフォームとリストビューをカスタマイズする方法について説明します。



All Articles