Russian (Pусский) translation by Sergey Zhuk (you can also view the original English article)
В предыдущей части серии мы создали специальную директиву для размещения записей на передней панели. Эта директива принимает аргументы непосредственно в атрибуте HTML, а также в URL для извлечения сообщений с сервера. Построение этой директивы позволило нам показать функцию публикации сообщений в любом месте приложения, повторно используя бизнес-логику и логику рендеринга, предусмотренную этой директивой.
В этой заключительной части серии мы будем работать над оставшейся частью наших контроллеров приложений и сборки для публикации сообщений, отдельной публикации, автора и категории. Мы также будем работать над шаблонами этих контроллеров и отображать на них данные, предоставленные контроллерами.
Чтобы быть более конкретными, в текущей части серии мы:
- Познакомимся с контроллерами AngularJS
- построим контроллеры для сообщений, категорий и пользователей
- соединим шаблоны с данными, предоставляемыми контроллерами
Итак, начнем с введения в контроллеры AngularJS.
Представляем AngularJS-контроллеры
Контроллеры в AngularJS являются одним из основных блоков приложения. Они содержат бизнес-логику, которая решает, какие данные отображать пользователю. Они управляют большей частью функциональных возможностей приложения, связанных с интерфейсом, а также обеспечивают поддержку для взаимодействия с пользователем.
Контроллеры тесно связаны с DOM, и они склеивают модель приложения - где находятся данные - с видом приложения.
В нашем случае, когда мы создаем приложение, основанное на WP REST API, контроллеры - это то место, где мы показываем данные, полученные через API, и различные услуги для конечного пользователя.
Построение контроллера для просмотра сообщения в листинге
Контроллеры в AngularJS определены в модуле, и мы будем использовать те же обозначения безопасного стиля внедрения зависимостей, что и для объявления пользовательской директивы. Рассмотрим следующий код, в котором мы объявляем контроллер для страницы публикации:
/** * Controller for Post Listing */ quiescentApp.controller( 'PostListing', [function() { var self = this; }] );
Контроллеры определяются в модуле с использованием метода .controller()
, который доступен в модуле. Имя контроллера, который мы определили выше, - PostListing
.
Любые данные, которые мы должны предоставить внешнему миру, должны быть установлены на ключевое слово this
внутри функции конструктора контроллера. Поэтому мы кэшируем ключевое слово this
, создавая переменную self
.
Контроллер для публикации сообщений является самым простым из всех контроллеров, которые мы сделаем, в том смысле, что он не должен иметь никаких данных. Для этого просто нужно связать шаблон, и мы разместим директиву <post-listing> </post-listing>
в этом шаблоне, чтобы начать публикацию записей. Директива будет извлекать сообщения самостоятельно с помощью службы Posts
и перечислять их, используя собственную логику рендеринга.
Поэтому в качестве первого шага мы свяжем шаблон views/listing.html с контроллером PostListing
, и мы сделаем это в секции .config()
нашего приложения. В разделе .config()
мы настроили маршруты для приложения, и нам нужно изменить маршрут /wp/v2/posts
следующим образом:
$route.when( '/posts', { templateUrl: 'views/listing.html', controller: 'PostListing', controllerAs: 'postListing' } )
В приведенном выше коде мы добавили два дополнительных свойства в определение маршрута, и эти свойства:
-
controller
: имя контроллера, который нам нужно связать с этим маршрутом и его шаблоном. -
controllerAs
: ключевое слово, по которому мы обращаемся к контроллеру в нашем шаблоне.
Поэтому мы передали PostListing
в качестве имени контроллера, и мы будем ссылаться на него в шаблоне, используя ключевое слово postListing
.
Связав контроллер с маршрутом и шаблоном, теперь нам нужно изменить шаблон для правильного отображения сообщений. Поэтому откройте файл шаблонов views/listing.html и замените его содержимое следующим кодом:
<post-listing></post-listing>
Ниже приведен скриншот завершенного шаблона:

Вот и все! Вышеупомянутая строка кода демонстрирует мощь директив AngularJS. С помощью всего лишь одной строки кода мы смогли подражать функциональности для листинга поста, включающего как бизнес-логику, так и логику рендеринга. И далее мы увидим, насколько гибкой может быть эта директива AngularJS при сборке контроллеров для категорий и пользователей, перечисляющих представления в следующих разделах.
Построение контроллера для представления категории
Ознакомившись с синтаксисом объявления контроллера и построив очень простой контроллер для публикации записей, мы готовы приступить к работе с более продвинутым контроллером для представления категорий.
Контроллер просмотра категорий, который мы создаем, будет использовать службу $routeParam
для доступа к идентификатору категории в URL, и используя этот идентификатор, контроллер будет использовать службу Categories
для извлечения информации о категории и списка связанных с ней сообщений. Однако контроллер не будет напрямую извлекать сообщения с помощью службы Posts
, а скорее будет использовать директиву postListing
и передать ей идентификатор категории, чтобы получить список сообщений, связанных с этой категорией.
Ниже приведен код для контроллера CategoryListing
:
/** * Controller for Categories */ quiescentApp.controller( 'CategoryListing', ['$routeParams', 'Categories', function( $routeParams, Categories ) { var self = this; self.categoryInfo = {}; Categories.get( {'id': $routeParams.id}, function( data, headers ) { self.categoryInfo = data; }); }] );
Контроллер CategoryListing
выше имеет две зависимости для службы $routeParams
и настраиваемой службы Categories
. Используя службу $routeParams
, он извлекает идентификатор категории из URL-адреса и затем запрашивает использование этого идентификатора для информации о категории через службу Categories
.
Контроллер имеет переменную, определенную в объекте $scope
с именем categoryInfo
. Эта переменная содержит объект категории, возвращаемый сервером, и его значение устанавливается после успешного выполнения запроса.
Следующее, что нам нужно сделать, - связать шаблон с этим контроллером, который отобразит данные пользователю. И мы делаем это в секции .config
приложения, как мы это делали для контроллера PostListing
в предыдущем разделе.
Поэтому измените маршрут /categories/:id
, чтобы он содержал следующий код:
// category profile route .when( '/categories/:id', { templateUrl: 'views/category.html', controller: 'CategoryListing', controllerAs: 'categoryListing' } )
В приведенном выше коде мы связываем маршрут с контроллером CategoryListing
, а также определяем ключевое слово categoryListing
, через которое мы обращаемся к нему в шаблоне.
Пришло время изменить шаблон views/category.html, чтобы он отображал данные динамически, а не показывал статический HTML-код.
<h2>Category: {{categoryListing.categoryInfo.name}}</h2> <post-listing post-args="{'filter[cat]': categoryListing.categoryId}"></post-listing>
В приведенном выше коде мы заменили имя категории с жесткой кодировкой на {{categoryListing.categoryInfo.name}}
, где categoryListing
является экземпляром контроллера CategoryListing
. Переменная categoryInfo
содержит объект категории, возвращаемый сервером, и этот объект содержит свойство name
для названия категории.
Для функции публикации сообщений мы используем директиву postListing
и передаем ей идентификатор категории через атрибут post-args
. Для этой цели мы используем синтаксис filter[]
, поддерживаемый маршрутом /wp/v2/posts
WP REST API. Мы уже знакомы с синтаксисом filter[]
из четвертой части вводной серии о WP REST API.
Ниже приведен скриншот завершенного представления категории:

Давайте теперь разработаем контроллер для пользователей, который очень похож на контроллер категорий.
Построение контроллера для представления пользователя
Контроллер для пользовательского представления очень похож на контроллер категорий. Мы начнем с изменения конфигурации маршрутизации, чтобы связать контроллер с шаблоном:
// author profile route .when( '/users/:id', { templateUrl: 'views/author.html', controller: 'UserListing', controllerAs: 'userListing' } )
Здесь мы связываем контроллер UserListing
с маршрутом и его шаблоном. Ключевое слово, по которому мы обращаемся к экземпляру контроллера, - userListing
.
Ниже приведен код для контроллера UserListing
:
/** * Controller for Users */ quiescentApp.controller( 'UserListing', ['$routeParams', 'Users', function( $routeParams, Users ) { var self = this; self.userInfo = {}; self.userId = $routeParams.id; Users.get( {'id': self.userId}, function( data, headers ) { self.userInfo = data; }); }] );
Контроллер UserListing
принимает в качестве зависимостей $routeParams
и Users
. Используя службу $routeParams
, он обращается к идентификатору пользователя в URL-адресе. Затем служба Users
используется для извлечения объекта пользователя с использованием идентификатора пользователя. Переменная userInfo
содержит объект пользователя, возвращаемый сервером.
Давайте теперь изменим шаблон views/author.html, чтобы отобразить эти данные пользователю. Замените все содержимое файла author.html следующим:
<!-- author box starts --> <div class="author-box row"> <figure class="author-gravatar columns medium-4"> <img ng-src="{{userListing.userInfo.quiescent_avatar_url}}" alt="{{userListing.userInfo.name}}"> </figure> <div class="author-info columns"> <h2 class="author-title">About {{userListing.userInfo.name}}</h2> <p>{{userListing.userInfo.description}}</p> </div> </div> <!-- author box ends --> <h2>Posts by {{userListing.userInfo.name}}</h2> <post-listing post-args="{author: userListing.userId}"></post-listing>
В приведенном выше коде мы получаем доступ к переменной userInfo
, определенной в области контроллера, которая содержит объект информации пользователя. Используя различные свойства этого пользовательского объекта, мы заменяем жестко запрограммированное имя пользователя, его gravatar и описание.
Для перечисления постов, автором которых является пользователь, мы используем директиву postListing
и передаем ему идентификатор пользователя в качестве значения параметра author
. Затем директива извлекает сообщения, используя службу Posts
.
Вот как должно выглядеть завершенное представление:

Четвертый и последний контроллер, над которым нужно работать в настоящее время, - это просмотр в виде одного сообщения, и мы это сделаем в следующем разделе.
Построение контроллера для одиночного представления сообщения
Представление для отдельной публикации несколько отличается от других, поскольку оно не будет использовать директиву postListing
, потому что директива использует шаблон, который больше подходит для страницы со списком публикаций. Кроме того, мы будем добавлять поддержку, чтобы показывать комментарии для одного сообщения в будущем, поэтому нам нужно иметь отдельный шаблон для одной записи, а не использовать тот же шаблон, что и для публикации в сообщениях.
В силу вышеизложенных причин мы будем использовать службу Posts
вручную в контроллере для одной записи, чтобы получить сообщение, основанное на его слаге
Давайте сначала сделаем быструю модификацию в одном маршруте поста, чтобы связать контроллер и шаблон:
// single post route .when( '/posts/:slug', { templateUrl: 'views/single.html', controller: 'SinglePost', controllerAs: 'singlePost' } )
Таким образом, имя контроллера для одного сообщения будет SinglePost
. Мы будем использовать ключевое слово singlePost
для ссылки на него в своем шаблоне.
Ниже приведен код для объявления контроллера:
/** * Controller for Single Post */ quiescentApp.controller( 'SinglePost', ['$routeParams', 'Posts', function( $routeParams, Posts ) { var self = this; self.postSlug = $routeParams.slug; self.post = {}; Posts.query( {'slug': self.postSlug}, function( data, headers ) { self.post = data[0]; }); }] );
В приведенном выше коде мы сначала извлекаем сообщение slug с помощью службы $routeParams
и сохраняем его в свойстве self.postSlug
в области действия контроллера. Затем мы запрашиваем базу данных с помощью службы Posts
, предоставляя сообщение slug в качестве аргумента запроса. Возвращаемые данные - это массив, содержащий один объект, и мы устанавливаем свойство self.post
в области с использованием этих возвращаемых данных. Просто!
Теперь для шаблона ниже приведено содержимое файла views/single.html:
<!-- post listing starts --> <article class="post-entry"> <h2 class="post-title"><a ng-href="#/posts/{{singlePost.post.slug}}">{{singlePost.post.title.rendered}}</a></h2> <figure class="post-thumbnail" ng-show="singlePost.post.quiescent_featured_image"> <img ng-src="{{singlePost.post.quiescent_featured_image}}" alt="Featured Image"> </figure> <p class="post-meta"> By <a ng-href="#/users/{{singlePost.post.author}}">{{singlePost.post.quiescent_author_name}}</a> in <a ng-href="#/categories/{{category.term_id}}" ng-repeat="category in singlePost.post.quiescent_categories">{{category.name}}{{$last ? '' : ', '}}</a> </p> <div class="post-content" ng-bind-html="singlePost.post.content.rendered"></div> <p class="back-to-listing"> <button class="button" onclick="window.history.back()">Back to posts listing</button> </p> </article> <!-- post listing ends -->
Вышеприведенный код довольно прост, поскольку мы связываем различные свойства пост-объекта с различными элементами, как мы это делали в последних нескольких разделах.
Ниже приведен скриншот завершенного просмотра одного сообщения:

Приложение теперь завершено (еще не совсем!) И предоставляет просмотры для публикации сообщений, отдельных сообщений, пользователей и категорий.
Заключение
Здесь мы завершаем нашу серию из четырех частей, в которой мы построили интерфейс, основанный на WP REST API и AngularJS. Мы начали с анализа требований и рассмотрения каркасов. Затем мы создали плагин-компаньон, который предоставляет некоторые дополнительные поля в стандартных ответах, которые понадобятся в нашем интерфейсе.
В следующих частях мы загрузили наше приложение AngularJS, раздельные шаблоны для разных представлений и настроили маршрутизацию приложений. Мы также создали специальную директиву AngularJS для функции публикации сообщений, которая абстрагирует функции публикации записей и обеспечивает гибкий способ получения набора записей для разных требований.
В заключительной части серии мы создали контроллеры для публикации сообщений, отдельных сообщений, категорий и пользовательских просмотров и связали их с их соответствующими шаблонами через раздел .config()
нашего приложения.
Приложение не является полным и может быть улучшено разными способами. Некоторые идеи перечислены ниже:
- Примечания в виде одного сообщения
- Сообщение No Posts by Author если на странице профиля автора нет сообщений
- Нумерованная пагинация страниц на страницах перечня публикаций
- Лучший SEO с одностраничными приложениями AngularJS
Мы попытаемся использовать эти возможности в будущих уроках. Но сейчас я оставляю это для вас, чтобы поразвлечься с приложением и расширить его с помощью некоторых потрясающих функций. Не забудьте предоставить онлайн-демонстрацию приложения в комментариях, так как я очень хочу учиться у моих читателей.
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post