Статьи

Создание конвертера валют с помощью jQuery Mobile и Cordova: логика перевода и преобразования

В предыдущей статье этой серии я описал пользовательскую конфигурацию jQuery Mobile для нашего приложения и подчеркнул важность предоставления междоменным запросам возможности загружать актуальные курсы обмена валют. Я также описал класс, который поможет нам перевести приложение на несколько разговорных языков, и я выделил второй класс для управления настройками пользователя. В этой четвертой статье я покажу вам классы, которые сохраняют, загружают и выполняют валютные операции, а также класс, объединяющий все различные компоненты нашего приложения.

Класс валюты

Когда я говорил о классе « Settings », я описал _tableName переменных _db и _tableName . Класс Currency имеет эти переменные и имеет ту же цель. Конечно, значение _tableName отличается, как и «валюты». Имейте в виду, что мы не храним объект — мы храним массив, содержащий экземпляры Currency . Мы должны хранить данные после последнего обновления или последних использованных валют; нам также нужно сохранить название валюты (фактически ее сокращение) и сам курс обмена.

Мы получаем ставки от Европейского центрального банка, и они используют евро в качестве справочных денег. Таким образом, когда вы анализируете канал, вы не найдете сам курс евро (предполагается, что он равен 1,00), и все ставки будут по отношению к евро. Это приводит к сложному методу сравнения валют не в евро, который я подробно объясню при описании метода convert() .

Исходя из того, что я уже сказал, начало класса Currency выглядит следующим образом:

 function Currency(abbreviation, rate) { var _db = window.localStorage; var _tableName = 'currencies'; this.abbreviation = abbreviation; this.rate = rate; } 

Как и в классе « Settings », у нас будут методы save() и load() . Последний идентичен тому, который уже обсуждался, в то время как первый тихо отличается, потому что мы управляем массивом. Поскольку мы не хотим дублировать валюты, нам нужно проверить, сохранена ли данная валюта, прежде чем добавлять в массив. Если валюта уже присутствует, мы просто обновим курс обмена. В противном случае мы поместим весь объект в массив. Для достижения этой цели я создам статический метод getIndex() , который возвращает индекс валюты, если она найдена, или возвращает false противном случае. Так же, как вы видели для класса Settings , я напишу статический метод утилиты для извлечения массива, содержащего экземпляры Currency называется getCurrencies() .

Теперь, когда вы знаете об этой сложной ситуации, я могу показать вам код методов save() и load() .

 this.save = function() { var currencyIndex = Currency.getIndex(this.abbreviation); var currencies = Currency.getCurrencies(); if (currencyIndex === false) currencies.push(this); else currencies[currencyIndex] = this; _db.setItem(_tableName, JSON.stringify(currencies)); } this.load = function() { return JSON.parse(_db.getItem(_tableName)); } 

Ниже приведен код для двух статических методов:

 Currency.getCurrencies = function() { var currencies = new Currency().load(); return (currencies === null) ? [] : currencies; } Currency.getIndex = function(abbreviation) { var currencies = Currency.getCurrencies(); for(var i = 0; i < currencies.length; i++) { if (currencies[i].abbreviation.toUpperCase() === abbreviation.toUpperCase()) return i; } return false; } 

Теперь, когда мы можем сохранять и загружать валюты, нам нужен метод для математического преобразования валют. Прежде чем показывать вам код методов, я должен подчеркнуть одну вещь. Как я уже сказал, в ленте используется евро в качестве базовой валюты, поэтому вы не будете хранить отдельные курсы обмена для каждой валюты — это будет пустая трата памяти. Мы разработаем метод конвертации евро в другие валюты для каждого желаемого типа валюты.

Теперь предположим, что вы хотите конвертировать из USD в AUD, что вы можете сделать? Решение заключается в том, что вы сначала конвертируете в евро, а затем в валюту, которая вам действительно нужна.

Чтобы достичь этой цели, вам нужно сначала поделить на начальный курс, а затем умножить на целевой курс валюты. Для метода convert() требуется три параметра: значение для преобразования, начальная валюта и целевая валюта. Этот метод основан на другом методе, называемом getRate() , который, используя abbreviation (сокращение названия валюты), получает соответствующий курс getRate() . getRate() опирается на метод, который я еще не объяснил, называется getCurrency() . Как вы можете себе представить, он очень похож на getCurrencies() , за исключением того, что он принимает аббревиатуру в качестве параметра и возвращает экземпляр Currency если поиск завершился успешно, или null если он не прошел.

Исходный код этих трех методов приведен ниже:

 Currency.getCurrency = function(abbreviation) { var index = Currency.getIndex(abbreviation); return (index === false) ? null : Currency.getCurrencies()[index]; } Currency.getRate = function(abbreviation) { var currency = Currency.getCurrency(abbreviation); return (currency === null) ? 0 : currency.rate; } Currency.convert = function(value, from, to) { // Round up to the 2nd decimal return Math.round(value / Currency.getRate(from) * Currency.getRate(to) * 100) / 100; } 

Последние два метода — это те, которые будут использоваться при обновлении полей выбора, чтобы выбрать валюты для сортировки по алфавиту. Их имена являются compareTo() и compare() , и их код выглядит следующим образом:

 Currency.prototype.compareTo = function(other) { return Currency.compare(this, other); } Currency.compare = function(currency, other) { if (other == null) return 1; else if (currency == null) return -1; return currency.abbreviation.localeCompare(other.abbreviation); } 

Сервисные функции

В этом разделе я расскажу о служебных функциях, содержащихся в файле functions.js . Обратите внимание, что я не буду объяснять updateIcons() , потому что он уже обсуждался и был представлен в предыдущей серии. Итак, если вы хотите понять, что он делает, вы можете прочитать раздел «Обновление значков на основе размера экрана» в Построение мобильного приложения на основе местоположения с HTML5 и Javascript: Часть 4 .

Тестирование на требования

«Конвертер валют» не предъявляет особых требований. Фактически, единственное обязательное условие, которое нам нужно, — это возможность хранить данные с помощью API веб-хранилища. Хотя возможность подключения к Интернету важна, она необходима только при первом запуске приложения, поскольку ему нужно будет загрузить последние тарифы из RSS-канала Европейского центрального банка. Но после этого пользователь может продолжать работать в автономном режиме с немного устаревшими курсами конвертации валют. Очевидно, что без подключения к Интернету мы не сможем обновлять тарифы.

Чтобы проверить требования, я создам функцию checkRequirements() , которая будет проверять поддержку API веб-хранилища. Если устройство не поддерживает его, приложение уведомляет пользователя, используя Cordova Notification API, и возвращает false , поэтому кнопку для обновления конвертации валют можно отключить. Код этой функции показан ниже.

 function checkRequirements() { if (typeof window.localStorage === 'undefined') { console.log('The database is not supported.'); navigator.notification.alert( 'Your device does not support the database used by this app.', function(){}, 'Error' ); return false; } return true; } 

Как вы видите, я также написал инструкцию console.log() чтобы помочь вам отладить проект в случае необходимости. Помните, что использование alert() не рекомендуется.

Перевод страниц

Чтобы перевести элементы index.html , я буду использовать API-интерфейс Globalization , представленный в Cordova 2.2.0., getPreferredLanguage() позволяет вам получать информацию о локали и часовом поясе пользователя, особенно благодаря таким методам, как getPreferredLanguage() (который получает клиентский текущий разговорный язык) и getLocaleName() (который получает код идентификатора текущей настройки языка клиента, например, en_US или it_IT).

Кроме того, этот API имеет методы для выполнения таких операций, как преобразование дат и чисел в строки с использованием надлежащего локального формата, основанного на настройках пользователя. Методы, которые реализуют эти преобразования: dateToString() и numberToString() соответственно. Обратите внимание, что, как и в других API-интерфейсах Cordova, эти методы являются асинхронными, поэтому они используют функции обратного вызова для успешных и неудачных вызовов.

В нашем проекте мы будем использовать некоторые из ранее цитируемых методов, а именно: getLocaleName() , dateToString() и numberToString() . Этот API очень важен, потому что он позволяет продвинуть пользовательский опыт на один шаг вперед по сравнению с тем, что вы могли сделать в предыдущих версиях. Обратите внимание, что в настоящее время поддерживаются следующие платформы: Android, BlackBerry WebWorks (OS 5.0+), iOS и Windows Phone 8.

Как вы увидите из приведенного ниже кода, я использовал метод getLocaleName() для получения идентификатора языка, который я буду использовать для получения правильного языка из объекта Translation . После получения я переберу текстовые строки, чтобы перевести различные учебные элементы. Теперь вы должны наконец понять, почему я использовал имя элемента как свойства. Вы также заметите использование Audero Text Changer для изменения текста элементов, что я иллюстрировал в первой части этой серии.

 /** * Translate the main page */ function translateMainPage() { navigator.globalization.getLocaleName( function(locale) { var translation = Translation[locale.value.substring(0, 2)]; if (typeof translation === 'undefined') return; for(var key in translation) $('#' + key).auderoTextChanger(translation[key]); }, function() { console.log('An error has occurred with the translation'); } ); } 

Вывод

В этой четвертой статье я описал класс Currency и все его методы. Как вы узнали, у него есть несколько служебных методов, которые позволяют вам писать новые методы с очень небольшим количеством строк кода. Я также показал, как тестировать минимальные требования к приложениям, и дал краткий обзор API глобализации, а также конкретные методы, используемые в нашем проекте. Чтобы помочь нам управлять переводом элементов интерфейса, я использовал плагин Audero Text Changer . В следующей части серии я покажу вам остальные functions.js файла functions.js чтобы завершить обсуждение.