Вебинар по Storage Optimization в SharePoint

В среду, 19.06.2013, будет проводиться вебинар на тему повышения эффективности хранения большого объема данных  в SharePoint.

Я буду рассказывать про основные проблемы, пути решения и best practicies. Партнеры из компании AvePoint расскажут о продуктах, которые помогут добиться результатов.

Целевая адуитория – архитекторы и администраторы порталов SharePoint.

Ссылка на описание и регистрацию: https://eu.avepoint.com/resources/webinars/?tab=ru&utm_source=iteco&utm_medium=webinar&utm_campaign=optimisation

Присоединяйтесь все, буду раз всех видеть или слышать. Количество мест ограничено.

UPD. Запись выложена здесь - http://eu.avepoint.com/assets/movie/webinar/russian/Webinar-Optimisation-Russian-June19-2013.html



Слайды с SPCUA и DevCon

За последние две недели я успел выступить с двумя докладами на конференция SharePoint Conferencе Ukraine 2013  в Киеве и DevCon 2013 в Москве.

Первый доклад посвящен вопросам аутентификации и авторизации в приложениях SharePoint 2013 (apps).

Второй доклад, который я делал совместно с Маратом Бакировым, о том как создавать приложения в SharePoint 2013.

Видеозаписи выступлений будут доступны позже.



Разработка приложений SharePoint 2013 с помощью TypeScript

Прошлый раз я описывал преимущества использования TypeScript для разработки приложений.

В этом посте я покажу как TypeScript поможет разрабатывать приложения для SharePoint 2013. В SharePoint 2013 были улучшены возможности разработки клиентских приложений на JavaScript. Это касается не только API, доступных на клиенте, но и механизмов поставки и развертывания приложений, инструментов разработчика. Более того, многие функции самого SharePoint 2013 реализованы и могу быть кастомизированы с помощью JavaScript.

SharePoint 2013 предлагает два вида API для использования на клиентской стороне: Client-Side Object Model (CSOM) и REST API. REST API позволяет манипулировать объектами на сервере используя REST (OData) веб-сервис. CSOM представляет из себя набор классов, семантически эквивалентных серверной объектной модели SharePoint. CSOM доступна как для JavaScript (также называют JSOM – JavaScript Object Model) , так и для .NET. Но в JavaScript, в отличие от .NET, недоступны метаданные и типизация. В этой статье будет рассмотрено именно применение JSOM.

TypeScript позволяет описать типы для JSOM и использовать статическую проверку типов и intellisense при разработке приложений. К сожалению готовых определений типов для SharePoint 2013 в открытом доступе нет.

Я и Андрей Маркеев создали проект на CodePlex, в котором сделали определения типов и кучу примеров приложений на TypeScript для SharePoint 2013. Ссылка на проект - http://sptypescript.codeplex.com/

Пример приложения

Для примера создам приложение, позволяющее отслеживать время на рабочем месте.

image

Подготовка

Для начала необходимо:

Для того чтобы при сборке проекта выполнялась компиляция  TypeScript необходимо добавить в .csproj файл следующие элементы:

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

 

Библиотеки и определения

Визуальный интерфейс будет создан с помощью библиотеки knockoutjs с расширением koLite.

Для того чтобы использовать эти библиотеки в проекте необходимо добавить следующие NuGet пакеты:

  • KoLite (knockoutjs добавится автоматически)
  • jquery.TypeScript.DefinitelyTyped
  • knockout.TypeScript.DefinitelyTyped
  • kolite.TypeScript.DefinitelyTyped

Последние три пакета представляют из себя .d.ts файлы, которые описывают типы для TypeScript.

Для работы с JSOM в TypeScript надо добавить в проект файл 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 принимает два коллбека, первый вызывается в случае успешного завершения, второй в случае неудачи. Внимание, указатель 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,  хотя внутри объекта лежит массив. Это все вызвано тем, что большая часть клиентской объектной модели сгенерирована из серверной объектной модели, и все коллекции требуют специальный паттерн для обхода. Он 100% соответствует коду .NET для обработки IEnumerable коллекций.

Обработка результатов запроса:

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 доверяет всем операциям приведения типов,  поэтому вам необходимо следить, чтобы они были корректными.

Обработка команд

В зависимости от текущего состояния модели выполняется Check-In или Check-Out

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

Операция Check-In заключается в создании нового элемента в списке 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();
        });
}

 

Противоположная операция – Check-Out – заполняет значения времени завершения и продолжительности в часах.

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();
        });
}

В обоих случаях используется один и тот же “паттерн”. Сначала формируется пакет команд для отправки на сервер, а после успешного применения изменения отражаются в модели.

Заключение

Полный код примера вы можете скачать по ссылке. Также рекомендую посмотреть код проекта и примеры использования определений TypeScript для SharePoint (source code), найдете много интересного.

Кстати сам код примера будет работать и в SharePoint 2010, но придется создать другой проект и по-другому развертывать артефакты решения, чтобы все вместе заработало.

А в следующий раз я расскажу как можно кастомизировать формы и представления списков в SharePoint 2013, и тоже с помощью TypeScript.



Почему вам стоит использовать TypeScript

Если вы еще не в курсе: JavaScript победил. На сегодняшний день это самый кроссплатформенный язык, доступный для любых устройств. На нем можно создавать веб-приложения (клиент и сервер), в том числе с оффлайн-режимом работы, десктопные приложения (для Windows 8), приложения для смартфонов и планшетов (PhoneGap), расширения для Microsoft Office, SharePoint и Dynamics. Код на JavaScript работает в СУБД, таких как MongoDB и даже Hadoop в Windows Azure (BigData однако).

На Javascript уже написаны Doom и эмулятор Linux. Фактически решая любую задачу, кроме написания модуля ядра ОС, вы встретитесь с JavaScript. Если вы еще не знаете JavaScript, то вам следует срочно начать его изучать.

У JavaScript  много недостатков

Многие разработчики испытывают такую реакцию на JavaScript:

image

(картинка взята отсюда)

Большую часть людей пугает отсутствие intellisense при наборе кода и манипуляции с HTML\CSS. Но это не самые большие проблемы.

Самая большая проблема JavaScript в том, что его придумал не Microsoft.

Основные недостатки JavaScript:

  • Динамическая типизация, которая вызывает множество регрессионных ошибок.
  • Отсутствие модульности. Нет ни модулей, ни классов, прототипное ООП рвет мозг тем, кто пишет на C++\Java\C#.
  • Неочевидное поведение во многих местах.

Для того чтобы не писать JavaScript были созданы компиляторы Java –> JavaScript, C# –> JavaScript, LLVM –> JavaScript. Но все это приводит к тому, что на программу на исходном языке накладываются существенные ограничения, а также существующие библиотеки для JavaScript не используются.

TypeScript исправляет часть недостатков

Microsoft, посмотрев на эту картину, решил что нужен язык, который с одной стороны исправляет проблемы, с другой стороны максимально близок к JavaScript, чтобы использовать существующие наработки.

Так и появился язык TypeScript (ссылка на оффсайт). TypeScript является надмножеством JavaScript. То есть любой корректный код на JavaScript также является корректным кодом на TypeScript.

TypeScript использует статическую типизацию, то есть все типы проверяются при компиляции. Кстати сам компилятор TypeScript написан на TypeScript и является open source (ссылка на репозитарий).

TypeScript добавляет возможность объявлять модули, классы и интерфейсы. Это позволяет масштабировать разработку сложных JavaScript приложений.

На выходе получается обычный JavaScript, который не требует дополнительных библиотек или специальных компонентов.

TypeScript в действии

При наборе кода в VisualStudio доступна богатая подсказка:

tsintellisence

Поддерживаются классы, аннотации и вывод типов, работает интерактивная отладка.

С легкостью можно использовать в TypeScript внешние библиотеки, например jquery:

image

При несовпадении типов компилятор ругается:

image

Компиляция TypeScript  происходит при сборке проекта, проверяя многие ошибки без запуска.

Ну и самая главная фича, от вида которой я чуть не расплакался:

image

Кто еще не до конца вдохновился может глянуть на raytracer на TypeScript, результат работы.

Как начать использовать TypeScript

Если вы используете VisualStudio, то вам необходимо поставить два расширения:

Тогда у вас появится вот такой режим редактирования:

Слева код на TypeScript, справа результат компиляции на JavaScript. Таким образом использование TypeScript поможет вам лучше понять и изучить JavaScript.

Тем, кто не использует visual studio, повезло чуть меньше. На сегодня доступны плагины для распространенных текстовых редакторов, а также инструменты командной строки.

Далее вам следует обязательно прочитать туториалы от настоящего папы, иногда стоит заглядывать в спецификацию.

Множество определений типов для популярных библиотек можно найти в проекте DefinitelyTyped. Судя по нику автора проекта это наш соотечественник.

Заключение

Это была вводная статья. В следующий раз больше примеров и реальное применение TypeScript.



Запись с доклада на SPC UA 2012

Прошел почти год с того момента, как я выступал на конференции в Киеве. Наконец-то организаторы выложили запись выступления.

Смотреть тут: http://sharepoint-channel.com/stanislav-vyshhepan-iskusstvo-upravleniya-sharepoint-kak-poluchit-maksimalnuyu-vygodu-dlya-biznesa-videozapis-doklada-na-spcua-2012