Для сегодняшней демонстрации я решил попробовать кое-что, на что я хотел выделить время — интеграцию с календарем на мобильном устройстве. К счастью, для этого есть отличный плагин — Calendar-PhoneGap-Plugin . Этот плагин предоставляет все типы хуков в локальный календарь, включая возможность поиска и добавления событий. С этим плагином я быстро набрал демо.
Я начал с создания приложения, которое просто возвращало события из списка и отображало их как есть. Вот мнение:
Давайте посмотрим на код, стоящий за этим. Во-первых, HTML. Поскольку это приложение очень простое, я не использую маршруты и шаблоны.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
</head>
<body ng-app="starter">
<ion-pane ng-controller="MainCtrl">
<ion-header-bar class="bar-stable">
<h1 class="title">Ionic Calendar Demo</h1>
</ion-header-bar>
<ion-content>
<div class="card" ng-repeat="event in events">
<div class="item item-divider">
{{event.title}}
</div>
<div class="item item-text-wrap">
{{ event.description }}
<p/>
<strong>When: {{ event.date | date:'short' }}</strong>
</div>
</div>
</ion-content>
</ion-pane>
</body>
</html>
Это все должно быть довольно котельной плитой. Я просто перебираю события и создаю пользовательский интерфейс для каждого из них. Теперь давайте посмотрим на код контроллера.
angular.module('starter.controllers', [])
.controller('MainCtrl', function($scope, Events) {
Events.get().then(function(events) {
console.log("events", events);
$scope.events = events;
});
});
Да, просто позвоните в службу и оформите события. Trivial. Теперь давайте посмотрим на сервис.
angular.module('starter.services', [])
.factory('Events', function($q) {
var incrementDate = function (date, amount) {
var tmpDate = new Date(date);
tmpDate.setDate(tmpDate.getDate() + amount)
return tmpDate;
};
//create fake events, but make it dynamic so they are in the next week
var fakeEvents = [];
fakeEvents.push(
{
"title":"Meetup on Ionic",
"description":"We'll talk about beer, not Ionic.",
"date":incrementDate(new Date(), 1)
}
);
fakeEvents.push(
{
"title":"Meetup on Beer",
"description":"We'll talk about Ionic, not Beer.",
"date":incrementDate(new Date(), 2)
}
);
fakeEvents.push(
{
"title":"Ray's Birthday Bash",
"description":"Celebrate the awesomeness of Ray",
"date":incrementDate(new Date(), 4)
}
);
fakeEvents.push(
{
"title":"Code Review",
"description":"Let's tear apart Ray's code.",
"date":incrementDate(new Date(), 5)
}
);
var getEvents = function() {
var deferred = $q.defer();
deferred.resolve(fakeEvents);
return deferred.promise;
}
return {
get:getEvents
};
});
Итак, это немного сложнее. У меня есть набор поддельных данных, которые создают четыре события в будущем. Служба затем возвращает эти поддельные события. Итак, давайте поднимем это на ступеньку выше. Учитывая, что наш плагин Календарь может проверять события, я собираюсь обновить свой код, чтобы отображать, было ли событие добавлено в календарь или нет. Вот пример.
На этом снимке экрана вы видите кнопки, чтобы добавить событие в свой календарь. Обратите внимание, что третье событие, однако, распознается как находящееся в календаре. Чтобы заставить это работать, я обновил сервисный вызов для событий, чтобы обработать проверку календаря. Это было немного сложно, поскольку каждый вызов асинхронный, но $ q облегчает его обработку.
var getEvents = function() {
var deferred = $q.defer();
/*
Logic is:
For each, see if it exists an event.
*/
var promises = [];
fakeEvents.forEach(function(ev) {
//add enddate as 1 hour plus
ev.enddate = incrementHour(ev.date, 1);
console.log('try to find '+JSON.stringify(ev));
promises.push($cordovaCalendar.findEvent({
title:ev.title,
startDate:ev.date
}));
});
$q.all(promises).then(function(results) {
console.log("in the all done");
//should be the same len as events
for(var i=0;i<results.length;i++) {
fakeEvents[i].status = results[i].length === 1;
}
deferred.resolve(fakeEvents);
});
return deferred.promise;
}
Я устанавливаю значение состояния для событий, чтобы показать, существует ли событие. Вернувшись на сторону дисплея, я справляюсь с этим так:
<p ng-if="event.status">This event is added to your calendar already!</p>
<button ng-if="!event.status" ng-click="addEvent(event,$index)" class="button button-block button-balanced">Add to Calendar</button>
Довольно просто, правда? Теперь давайте посмотрим на код добавления. Я пропущу код контроллера, так как все, что он делает, это вызывает службу и обновляет область.
var addEvent = function(event) {
var deferred = $q.defer();
$cordovaCalendar.createEvent({
title: event.title,
notes: event.description,
startDate: event.date,
endDate:event.enddate
}).then(function (result) {
console.log('success');console.dir(result);
deferred.resolve(1);
}, function (err) {
console.log('error');console.dir(err);
deferred.resolve(0);
});
return deferred.promise;
}
И просто чтобы доказать, что это работает — вот событие, которое я только что добавил:
Я поместил полный исходный код для этой демонстрации на GitHub: https://github.com/cfjedimaster/Cordova-Examples/tree/master/calendarionic . Я хочу поблагодарить Эдди Вербруггена за помощь в использовании его плагина и за исправление ошибки, с которой я столкнулся!