Автор Джен Лупер для блога Telerik.
Создание приложений с использованием гибридных мобильных технологий позволило разработчикам развернуть красивые продукты в рекордно короткие сроки. Недавно я заполнил целое приложение от эскиза до запуска за одну неделю, чтобы поймать праздничных покупателей. Создание отличного пользовательского интерфейса с использованием хороших инструментов разработки веб-интерфейса упрощает работу с визуальной точки зрения, но настоящая сущность приложения — его данные, поэтому нам нужен быстрый способ создания веб-интерфейса и надежный способ подключить его к надежному бэкэнду. , Для моего недавнего проекта приложения и для этого учебного руководства я использовал серверные службы Ionic и Telerik, которые являются частью платформы Telerik и предоставляют чрезвычайно удобное решение для управления данными, разработанное специально для разработчика, которому нужна скорость, точность, безопасность и простота. из-развертывания.
В этой серии руководств мы собираемся создать проект как раз вовремя, чтобы отдать его на праздники — приложение для использования в муниципальной кладовой или в продовольственном банке.
Оставайтесь с нами позже в серии для объявления об этом проекте! Оповещение о спойлере: выигрыш!
Я собираюсь назвать это приложение «Pntry» (потому что удаление гласных делает вещи крутыми). Вариант использования состоит в том, чтобы связать потребности местных продовольственных банков с донорами и клиентами, чтобы продовольственные банки могли более эффективно удовлетворять потребности своих клиентов, а доноры могли узнать, что необходимо, и настроить свои пожертвования.
Это довольно сложный проект, поэтому я собираюсь разбить эти уроки на три части:
- В первой части мы настроим нашу рабочую среду и завершим экраны входа и регистрации.
- Во второй части мы создадим формы банка продуктов питания, с помощью которых они запрашивают пожертвования определенных продуктов питания.
- В третьей части мы создадим приложение на основе ролей, создав области для использования банком продуктов питания и области для использования донором.
Давайте начнем!
Примечание. На данный момент я использую инструменты Ionic CLI для локального создания приложения, но в следующем уроке мы собираемся перенести нашу кодовую базу в платформу Telerik. Это еще больше ускорит разработку и предоставит доступ к превосходному набору инструментов разработчика, предлагаемых Платформой. На данный момент, однако, мы собираемся строить локально, чтобы настроить наш рабочий процесс.
Это просто, чтобы создать базовое приложение для Ionic и быстро его обработать. Следуйте этим инструкциям, чтобы установить Ionic. В командной строке убедитесь, что вы находитесь в каталоге, в котором хотите работать, и создайте приложение, введя:
$ ionic start pntry sidemenu
Эта команда запускает процесс создания леса Ionic:
Измените каталоги на каталог pntry, который был только что создан:
$cd pntry
… И введите:
$ionic serve
Если вы правильно установили все зависимости Ionic, откроется окно браузера, в котором отображается базовое приложение с некоторыми заглушенными данными:
Мы собираемся изменить приложение, чтобы создать что-то вроде этого:
Я разобрал этот Ionic-проект до отказа и создал базовое приложение, которое доступно вам в GitHub. Это просто скелетное приложение с несколькими цветами, и большинство страниц, которые мы хотим использовать, предварительно созданы и связаны с боковым меню, к которому я добавил иконки, потому что я немного схожу с ума по иконкам. Загрузите этот код и замените /wwwпапку в только что созданном приложении Ionic на /wwwпапку в этой кодовой базе. Перезапустите Ionic, набрав rв терминале; Вы должны увидеть новую кодовую базу.
Примечание. Если у вас уже установлен Ionic и вы знакомы с процессом установки, вы можете просто выйти из любых запущенных в данный момент процессов Ionic, извлечь этот базовый проект из github и разархивировать его, перейдите в папку, в которой находится код, и введите
$ionic serve
Приложение должно выглядеть так:
… и с открытым боковым меню:
Структурирование приложения
Ионные приложения изначально включают в себя внешний вид, контроллер и заглушенную модель, жестко запрограммированную в контроллере. Нам нужен надежный сервисный уровень для обработки наших данных. Для этого мы собираемся отделить контроллер от уровня данных, создав services.jsфайл.
Ниже приведено базовое описание различных файлов JavaScript в приложении:
app.jsвключает в себя маршруты, которые необходимо знать приложению для перехода от страницы к страницеcontrollers.jsсодержит функции, которые позволяют пользователю взаимодействовать с внешним интерфейсом так, чтобы данные достигали внутреннего интерфейсаservice.jsобрабатывает взаимодействие между приложением и серверной частью и возвращает данные обратно во внешний интерфейс, где они отображаются, без необходимости обновления страницы из-за двусторонней привязки данных Angular. Это все довольно волшебно.
Идите вперед и добавьте services.jsфайл в /www/jsпапку. Мы уточним это, работая над этим учебником. Добавьте ссылку на этот файл index.htmlпод ссылкой controllers.js:
<script src="js/services.js"></script>
Добавьте следующую строку в services.jsфайл:
angular.module('pntry.services', [])
Добавьте ссылку на этот сервисный файл в первой строке app.js:
angular.module('pntry', ['ionic', 'pntry.controllers', 'pntry.services'])
Включение внутренних сервисов
Теперь пришло время подключить Telerik Backend Services к нашему веб- интерфейсу, чтобы мы могли заставить эти процедуры входа в систему и регистрации действительно что-то делать. Backend Services — это облачное решение для хранения данных вашего приложения. Чтобы получить к нему доступ, мы собираемся использовать JavaScript SDK (хотя это не относится к нашему приложению, существует множество других доступных интеграций — вы можете узнать больше, прочитав документацию .
Включите файл Backend Service в вашу кодовую базу. Самый простой способ сделать это — установить его через Bower (обратите внимание, что он использует прежнее имя Backend Services, Everlive):
$bower install everlive
Если у вас не установлен Bower, вы можете легко установить его через npm, используя
npm install -g bower
Bower устанавливает файлы в bower_componentsпапку в корне. Переместите everlive.all.min.jsфайл, установленный Bower, в новую www/lib/everliveпапку и укажите его index.htmlпод строкой со ссылкой на ionic.bundle.js:
<script src="lib/everlive/min/everlive.all.min.js"></script>
Перейдите на платформу Telerik и войдите в систему.
Не беспокойтесь, если у вас нет учетной записи Telerik Platform; Вы можете попробовать это бесплатно в течение 30 дней .
Создайте новое рабочее пространство с именем Pntry и нажмите зеленую кнопку, чтобы создать проект Backend Services.
Вы собираетесь начать с нуля в этом проекте.
Backend Services поставляется с некоторыми очень приятными функциями, в первую очередь для наших целей это объект Users , который похож на таблицу базы данных, которая будет заполняться нашими зарегистрированными пользователями.
Мы собираемся сохранить отображаемое имя, имя пользователя, пароль, адрес электронной почты и название банка продуктов питания в нашей регистрационной форме и сохранить эти данные в объекте Users.
Когда пользователь успешно заполняет форму, кроме того, автоматически генерируется электронное письмо от Бэкэнда, чтобы приветствовать пользователя в сети. Backend поставляется с предварительно настроенными четырьмя шаблонами электронной почты для общих случаев использования при регистрации и управлении паролями.
Получите ключ API из области API Key Платформы.
Теперь мы можем начать улучшать наш сервисный слой. В этом services.jsфайле добавьте наш первый объект Factory и добавьте свой собственный ключ API:
angular.module('pntry.services', [])
.factory('API', function() {
var api_key = 'your-api-key';
return api_key;
});
Примечание: лучшие практики требуют, чтобы вы не хранили свой ключ API в своем приложении, а скорее создавали спокойную конечную точку, из которой вы можете доставить ключ … но это тема для другого урока!
Наш сервисный слой будет содержать все обращения к бэкэнду. Другие сервисные функции смогут получить доступ к этому ключу API, вызвав фабрику.
Заполните регистрационную форму
Пока мы находимся в области Backend Services, давайте добавим еще одно поле, которое мы хотим записать при регистрации. Это будет название организации, чтобы мы могли определить название банка продуктов питания. В области «Пользователи» щелкните значок структуры данных справа:
Добавьте элемент в таблицу Users с именем OrganizationName и нажмите «добавить» и «сохранить».
Добавьте поле /www/templates/register.htmlпод открывающим элементом списка карт, чтобы новое поле ввода появилось вверху регистрационной формы:
<label class="item item-input"> <span class="input-label">Organization Name</span> <input type="text" name="displayname" ng-model="registerData.organizationname"></label>
Завершите функции регистрации
Теперь нам нужно обработать регистрационную форму. Мы начнем с создания фабрики пользователей в services.jsрамках фабрики API:
.factory('User', function (API) {
var el = new Everlive({
apiKey: API,
url: '//api.everlive.com/v1/',
scheme: 'https'
});
return {
register: function(registerData){
return el.Users.register(
registerData.username,
registerData.password,
{
Email: registerData.email,
DispayName: registerData.displayname,
OrganizationName: registerData.organizationname
})
.then(function (data) {
return data;
},
function(error) {
return error;
});
}
}
});
Затем включите controller.jsиспользование этой новой фабрики, добавив ее ссылку в начало этого файла. Мы также используем некоторые дополнительные возможности, предоставляемые Ionic для пользовательского интерфейса, поэтому убедитесь, что вершина controller.jsнапоминает эту строку:
.controller('AppCtrl', function($state, $scope, $ionicModal, $ionicPopup, User) {...
В том числе
$stateпозволяет нам перейти на новую страницу после регистрации и авторизации.$ionicPopupэто чистое маленькое всплывающее окно, которое полезно для отображения ошибок регистрации, сгенерированных из серверной части. И пользователь — это имя фабрики, которую вы создали на уровне сервисов. В вашем контроллере ссылайтесь на заводскую настройкуUser.register, чтобы передавать данные обратно и обратно в сервис.
Наконец, уточните doRegister()функцию в контроллере:
// Perform the register action when the user submits the registration form
$scope.doRegister = function() {
User.register($scope.registerData).then(function(data){
if(data.result){
//log me in
$scope.loginData.username = $scope.registerData.username;
$scope.loginData.password = $scope.registerData.password;
$scope.doLogin();
$scope.closeRegister();
$state.go("app.inventory");
}
else{
$ionicPopup.alert({
title: status.data.message,
template: 'Please try again!'
});
}
});
}
Теперь вы сможете открыть регистрационную форму в своем приложении, заполнить ее, нажать «Зарегистрироваться» и просмотреть свои данные в Backend Services в таблице «Пользователь».
Создание логина и аутентификации
По умолчанию сгенерированный нами проект Ionic поставляется со встроенным экраном входа. Мы собираемся добавить к нему экран регистрации, чтобы продовольственная кладовая могла создавать профиль и иметь собственные данные. Большая часть приложения должна быть защищена паролем, поэтому мы собираемся сохранить токен, сгенерированный Backend Services, чтобы помочь с нашей аутентификацией.
Добавьте loginфункцию в services.jsфабрику пользователей под функцией регистрации:
login: function(loginData) {
return el.Users.login(
loginData.username,
loginData.password)
.then(function (data) {
return data;
},
function(error) {
return error;
});
},
Теперь в контроллере все становится интересным. Мы собираемся использовать localStorage для сохранения токена, который Backend Service отправляет обратно, чтобы мы могли использовать его в будущих взаимодействиях.
Перезаписать текущую doLoginфункцию следующим кодом:
// Perform the login action when the user submits the login form
$scope.doLogin = function() {
User.login($scope.loginData).then(function(data){
if(data.result){
localStorage.setItem("token",data.result.access_token);
$state.go("app.inventory");
$scope.loginmodal.hide();
}
else{
$ionicPopup.alert({
title: data.message,
template: 'Please try again!'
});
}
});
};
Наконец, мы можем добавить тест, чтобы убедиться, что у нас есть токен и что он действителен; если это не так, мы вернем пользователя обратно на домашнюю страницу; если это так, мы разрешаем доступ к данной области. Добавьте этот фрагмент кода выше предыдущего кода:
$scope.testLoginStatus = function() {
var token = localStorage.getItem("token");
User.me(token).then(function(data){
console.log(data)
if(!data.result){
$ionicPopup.alert({
title: 'Your session has expired',
template: 'Please login!'
});
//go home
$state.go("app.home");
}
});
};
Теперь мы можем создать сервис для проверки статуса пользователя и убедиться, что токен аутентификации был установлен при входе в систему:
//am I logged in with a valid token?
me: function(token) {
return el.Users.currentUser(
{headers: {'Authorization':'Bearer '+token}})
.then(function (data) {
return data;
},
function(error) {
return error;
});
}
Добавьте тест токена click ( ng-click="testLoginStatus()") для каждого элемента меню в /www/templates/menu.html:
<ion-list>
<ion-item nav-clear menu-close ng-click="testLoginStatus()" href="#/app/donationrequests">
<i class="icon ion-help-buoy"></i> Donation Requests
</ion-item>
<ion-item nav-clear menu-close ng-click="testLoginStatus()" href="#/app/requestdonation">
<i class="icon ion-speakerphone"></i> Request A Donation
</ion-item>
<ion-item nav-clear menu-close ng-click="testLoginStatus()" href="#/app/inventory">
<i class="icon ion-clipboard"></i> Inventory
</ion-item>
<ion-item nav-clear menu-close ng-click="testLoginStatus()" href="#/app/needs">
<i class="icon ion-compose"></i> Current Needs
</ion-item>
</ion-list>
Проверка в реальных условиях
Теперь весь controllers.jsфайл должен выглядеть так:
angular.module('pntry.controllers',[])
.controller('AppCtrl', function($state, $scope, $ionicModal, $ionicPopup, User) {
// Form data for the login modal
$scope.loginData = {
username: null,
password: null
};
$scope.registerData = {
username: null,
password: null,
email: null,
displayname: null,
organizationname: null
};
// Create the login modal that we will use later
$ionicModal.fromTemplateUrl('templates/login.html', {
scope: $scope
}).then(function(loginmodal) {
$scope.loginmodal = loginmodal;
});
// Create the login modal that we will use later
$ionicModal.fromTemplateUrl('templates/register.html', {
scope: $scope
}).then(function(registermodal) {
$scope.registermodal = registermodal;
});
$scope.testLoginStatus = function() {
var token = localStorage.getItem("token");
User.me(token).then(function(data){
console.log(data)
if(!data.result){
$ionicPopup.alert({
title: 'Your session has expired',
template: 'Please login!'
});
//go home
$state.go("app.home");
}
});
};
//open/close routines
$scope.openLogin = function() {
$scope.loginmodal.show();
};
$scope.closeLogin = function(){
$scope.loginmodal.hide();
};
$scope.openRegister = function() {
$scope.registermodal.show();
};
$scope.closeRegister = function(){
$scope.registermodal.hide();
};
// Perform the login action when the user submits the login form
$scope.doLogin = function() {
User.login($scope.loginData).then(function(data){
if(data.result){
localStorage.setItem("token",data.result.access_token);
$state.go("app.inventory");
$scope.loginmodal.hide();
}
else{
$ionicPopup.alert({
title: data.message,
template: 'Please try again!'
});
}
});
};
// Perform the register action when the user submits the registration form
$scope.doRegister = function() {
User.register($scope.registerData).then(function(data){
if(data.result){
//log me in
$scope.loginData.username = $scope.registerData.username;
$scope.loginData.password = $scope.registerData.password;
$scope.doLogin();
$scope.closeRegister();
$state.go("app.inventory");
}
else{
$ionicPopup.alert({
title: status.data.message,
template: 'Please try again!'
});
}
});
}
});
```
and the entire services.js file looks like this:
```
angular.module('pntry.services', [])
.factory('API', function() {
var api_key = 'your-api-key';
return api_key;
})
.factory('User', function (API) {
var el = new Everlive({
apiKey: API,
url: '//api.everlive.com/v1/',
scheme: 'https'
});
return {
register: function(registerData){
return el.Users.register(
registerData.username,
registerData.password,
{
Email: registerData.email,
DispayName: registerData.displayname,
OrganizationName: registerData.organizationname
})
.then(function (data) {
return data;
},
function(error) {
return error;
});
},
login: function(loginData) {
return el.Users.login(
loginData.username,
loginData.password)
.then(function (data) {
return data;
},
function(error) {
return error;
});
},
me: function(token) {
return el.Users.currentUser(
{headers: {'Authorization':'Bearer '+token}})
.then(function (data) {
return data;
},
function(error) {
return error;
});
}
}
});
Ура!
Мы успешно создали интерфейс для нашего приложения с базовой безопасностью, включая процедуры регистрации и входа в систему, соединяя интерфейс Ionic с Telerik Backend Services. В процессе мы создали прочную структуру для нашего приложения со слоем сервисов, отделенным от контроллера и представления, как нас научила мама. В следующем уроке мы создадим четыре экрана, которые банк продуктов сможет использовать для запроса пожертвований и управления запасами.
Изображение заголовка любезно предоставлено WEBN-TV










