Очень распространенной проблемой при кодировании JavaScript являются конфликты между двумя переменными с одинаковыми именами в глобальном пространстве имен. Если вы пишете код в нескольких файлах JS, возможно, например, var i используется более одного раза. Этого можно легко избежать, используя пространства имен следующим образом:

[code lang="js"]var AP = window.AP || {};[/код]

Этот оператор загружает AP из глобального пространства имен, если оно уже существует, и в противном случае создает новое AP пространства имен. Функции или переменные, созданные в этом пространстве имен, никогда не будут конфликтовать с теми же именами функций или переменных в другом пространстве имен. #победа!

[code lang="js"]AP.WebPropQuery = function() { var i = 0; };
AP.ContactsQuery = function() { var i = 1; };[/код]

Это делает код удобным и читабельным, в то время как var i теперь всегда является правильным значением в правильном контексте. Если вы хотите узнать больше, это отличное чтение:



Угловой JS

Моя цель здесь состояла в том, чтобы использовать практику пространства имен с написанным Angular. У Angular также есть способ охвата всего, и мне было сложно совместить его с этим подходом пространств имен.

С помощью директивы в HTML-коде «ng-app» мы указываем область действия этого приложения Angular. Используя этот код, я регистрирую его как модуль, чтобы позже также использовать службу.

[code lang="js"]AP.Promise = angular.module('AP.Promise', []);[/code]

Моя цель в этом примере — загрузить свойство из Web’s Propertybag. Это свойство содержит имя списка контактов. Я хочу, чтобы все контакты отображались с полным именем и адресом электронной почты.

Контроллеры

Контроллер в шаблоне MVC обрабатывает определенную часть представления. В нашем случае список контактов. Я использовал директиву ng-controller="ContactController" и соответствующий код JS.

[code lang=”js”]/*
* Регистрация контроллера Angular
* Зависимости: $scope и $ProfileService
*/
AP.Promise.controller('ContactController' , ['$scope', '$ContactService', function ($scope, $ContactService) {
$scope.contacts = [];
$ContactService.getContacts($scope);
}]);[/код]

При добавлении этого контроллера в модуль я передаю 2 зависимости. $scope (что является обязательным, иначе контроллер был бы бесполезен) и $ContactService. В этой службе хранится логика для получения данных из SharePoint. Содержание услуги

[code lang=”js”]/*
* Регистрация службы Angular для поддержки взаимодействия с SharePoint
*/
AP.Promise.service('$ContactService', function () {
> //Служебный метод для получения контактов
this.getContacts = function ($scope) {
// Логика
};
});[/code]

Это основа нашего кода Angular. Теперь нам нужно немного JS, чтобы получить данные из SharePoint. В этом примере я использую REST API.

REST вызовы и обещания

Одна библиотека, которая упрощает нашу жизнь при использовании REST API, — это jQuery. Вы могли заметить, что символ $ char очень популярен и используется многими библиотеками JavaScript. Мы должны быть осторожны, чтобы не вызвать здесь не ту библиотеку.

В начале этого поста я создал две функции в пространстве имен AP, которые мы собираемся заполнить. Один для вызова для получения веб-ресурса и один для вызова для получения контактов.

[code lang=”js”]/*
* Объект запроса для извлечения свойства из Propertybag
* Возврат: объект Promise, заполненный данными после возврата вызова ASync
*/
AP.WebPropQuery = function ($) {
var deferred = $.Deferred();
var execute = function () {
$.ajax({
url: _spPageContextInfo .webAbsoluteUrl + «/_api/web/AllProperties?$select=p42contacts»,
метод: «GET»,
заголовки: { «accept»: «application/json;odata=verbose» },< br /> успех: function (data) {
deferred.resolve(data);
},
error: function (err) {
deferred.reject(err);< br /> }
});
return deferred;
};
return {
выполнить: выполнить
}
}(jQuery) ;[/код]

Вот как выглядит первая функция. Теперь важная часть — обещание var deferred = $.Deferred(); Эта переменная называется обещанием и чем-то вроде заполнителя объекта, с которым вы можете работать до тех пор, пока асинхронный вызов не заменит объект конечным результатом вызова. Используя эти промисы, вам не нужно вкладывать второй вызов в функцию успеха вызова $.ajax. Это повышает удобочитаемость и ремонтопригодность вашего кода. Скотт Хиллиер написал отличную статью об обещаниях и о том, как их использовать:
https://curah.microsoft.com/11711/using-promises-patterns-in-sharepoint-2013-apps-with-javascript-and -jquery

Выполнение вызовов функций

Последний недостающий элемент — вызовы функций из логики службы Angular. Опять код сервиса с отсутствующей логикой

[code lang=”js”]/*
* Регистрация службы Angular для поддержки взаимодействия с SharePoint
*/
AP.Promise.service('$ContactService', function () {
> //Служебный метод для получения контактов
this.getContacts = function ($scope) {
//Первый асинхронный вызов
AP.WebPropQuery.execute().promise().then( function (data) {
//Второй асинхронный вызов в зависимости от данных первого вызова
AP.ContactsQuery.execute(data.d.p42contacts).promise().then(function (data) {
//Данные для работы
var results = data.d.results;
for (var i = 0; i ‹ results.length; i++) {
$scope.contacts. push({ fullname: results[i].FullName, email: results[i].Email });
}
//Применить область для просмотра результатов
$scope.$apply() ;
}, функция (ошибка) { });
}, функция (ошибка) { });
};
});[/code]

AP.WebPropQuery.execute() — это обычный вызов функции. С помощью .promise().then() теперь можно добавить второй вызов функции на основе обещания, возвращаемого первым. Этот второй вызов также возвращает обещание, и с помощью этих данных мы можем заполнить нашу модель.

Вид

Представление, соответствующее всему этому коду JS, представляет собой очень простой и простой фрагмент HTML.

[code lang="html"]
‹script type="text/javascript" src="/Style Library/Scripts/p42.contacts.js"›‹/script›
‹div ng-app ="AP.Promise"›
‹div ng-controller="ContactController"›
‹ul›
‹li ng-repeat="контакт в контактах"›{{contact.fullname} } — {{contact.email}}‹/li›
‹/ul›
‹/div›
‹/div›
[/code]

Результаты

Что мне действительно нравится в этой комбинации промисов и Angular, так это то, что ваш JavaScript имеет очень четкую структуру. Он очень удобен для чтения и сопровождения, и, кроме того, он очень быстрый! Таким образом, нам не нужно ждать загрузки всех JS-файлов SharePoint, поскольку мы используем REST API. Очень мощная штука!

Вы можете скачать решение Visual Studio 2012 здесь. Это решение содержит изолированное решение (по-прежнему подходит для подготовки материалов!) С веб-частью редактора сценариев по умолчанию, которая содержит представление HTML с директивами Angular.

Что сделать самому:

- Создайте список контактов и убедитесь, что полное имя и адрес электронной почты заполнены
- Создайте свойство с помощью SP Designer под названием «p42contacts» в корневой сети и добавьте имя списка контактов в качестве значения.