Состояния, параметры, файлы и документы
Реализация команд: ссылки и всплывающие элементы параметров
С технической точки зрения внутри функции invoked команды параметров вы можете делать все, что угодно. Правда! Конечно, как описано выше в руководстве по дизайну, есть рекомендации, касающиеся того, как следует и как не следует использовать эти команды. Например, команды в панели параметров не должны действовать как команды панели приложения, которые воздействуют на содержимое, их не следует использовать для навигации внутри приложения. В идеальном варианте эти команды выполняют одну из двух функций: либо открывают гиперссылки (в браузере), либо отображают дополнительные панели параметров.
На базе модели параметров WinRT, при открытии гиперссылки используется API Windows.System.Launcher.launchUriAsync (http://msdn.microsoft.com/library/windows/apps/hh701480.aspx) как показано ниже:
function helpCommandInvoked(e) { var uri = new Windows.Foundation.Uri("http://example.domain.com/help.html"); Windows.System.Launcher.launchUriAsync(uri).done(); }
Во втором случае дополнительные панели реализуются с помощью элемента управления WinJS.UI.SettingsFlyout (http://msdn.microsoft.com/library/windows/apps/hh701253.aspx). Опять же, с технической точки зрения, вы не обязаны использовать этот элемент управления: вы можете отобразить в обработчике invoked любой пользовательский интерфейс, какой хотите. Элемент управления SettingsFlyout, однако, предоставлен для обеспечения рекомендованного узкого и широкого размера, поддерживает анимацию при появлении и исчезновении, запускает события наподобие [before | after][show | hide] 3Как насчет краткой комбинации из четырех имен событий? Стоит так же отметить, что будет срабатывать событие document.body.DOMNodeInserted, когда всплывающий элемент будет появляться. и имеет другие полезные возможности. И хотя вы можете поместить любой HTML-код в элемент управления, включая другие элементы управления, и обычный всплывающий элемент поддерживает вертикальную прокрутку, на самом деле нет причин не использовать его.
Так как он является элементом управления WinJS, вы можете объявить SettingsFlyout для каждой из ваших команд в разметке (убедившись в том, что вызван WinJS.UI.process/processAll, благодаря чему будут обработаны другие элементы управления во всплывающем элементе). Например, Сценарий 2 примера "Параметры приложения" (http://code.msdn.microsoft.com/windowsapps/App-settings-sample-1f762f49) содержит следующий всплывающий элемент, отображающий справку (здесь текстовое содержимое опущено, код немного переформатирован), в результате получается то, что показано на рис. 2.4.
<div data-win-control="WinJS.UI.SettingsFlyout" aria-label="Help settings flyout" data-win-options="{settingsCommandId:'help', width:'wide'}"> <!-- Используем либо 'win-ui-light' либо 'win-ui-dark' в зависимости от различия цвета заголовка и фона; фоновый цвет отражает индивидуальность приложения --> <div class="win-ui-dark win-header" style="background-color:#00b2f0"> <button type="button" onclick="WinJS.UI.SettingsFlyout.show()" class="win-backbutton"></button> <div class="win-label">Help</div> <img src="../images/smallTile-sdk.png" style="position: absolute; right: 40px;"/> </div> <div class="win-content "> <div class="win-settings-section"> <h3>Settings charm usage guidelines summary</h3> <!-- Другое содержимое опущено --> <li>For more in-depth usage guidance, refer to the <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh770544"> App settings UX guide</a>.</li> </div> </div> </div>
Как всегда, у этого элемента управления есть параметры, так же, как и несколько применимых классов стилей win-*. Есть два параметра, это settingCommandId, идентификатор элемента, назначение которого очевидно, и width, который может принимать значения 'narrow' или 'wide'. И тот и другой присутствуют в вышеприведенном примере. Здесь применены стили win-settingsflyout, который задает стиль всего элемента управления (обычно не используется, за исключением основы для других правил стиля), а так же win-ui-light и win-ui-dark, которые применяют темную или светлую тему к частям всплывающего элемента. В данном примере использована темная тема для заголовка, в то время как остальные части элемента управления стилизованы с помощью светлой темы по умолчанию.
Рис. 2.4. Всплывающий элемент среди параметров, отображающий справку (обрезанный вертикально) из Сценария 2 примера о "Параметры приложения". Обратите внимание на гиперссылку в правом нижнем углу
В любом случае, вы можете видеть, что все внутри элемента управления – это обычная разметка для содержимого, ничего больше, и вы можете подключать события к элементам управления в разметке или в коде. Вы можете использовать здесь гиперссылки, например, для того, чтобы открыть полную версию справочной информации в браузере. Так же вы можете использовать iframe для непосредственной поддержки веб-содержимого внутри всплывающего элемента, как показано в Сценарии 3 того же примера.
Как мы показываем этот всплывающий элемент, когда активирована команда верхнего уровня на панели параметров? Самый простой способ – позволить WinJS позаботиться о деталях, используя сведения, которые вы предоставили для WinJS.UI.SettingsFlyout.populateSettings. Вот пример, снова из Сценария 2, который мы видели в предыдущем разделе:
e.detail.applicationcommands = { "help": { title: "Help", href: "/html/2-SettingsFlyout-Help.html" } }; WinJS.UI.SettingsFlyout.populateSettings(e); };
В JSON-коде, который вы назначили applicationCommand, каждый объект определяет и команду и связанный с ней всплывающий элемент. Имя объекта – это id всплывающего элемента ("help"), его свойство title задает надпись для команды верхнего уровня на панели параметров ("Help"), свойство href задает HTML-страницу, где описан всплывающий элемент с заданным id ("/html/2-SettingsFlyout-Help.html").
Используя эту информацию, WinJS может и заполнить панель параметров верхнего уровня, и обеспечить автоматическую активацию нужного всплывающего элемента (вызывая WinJS.UI.Process для этого), и вам не нужно писать для этого какой-либо код. Поэтому в сценариях примера вы не увидите явного вызова showSettings, а лишь вызовы populateSettings.
Вызов всплывающего элемента параметров из программного кода
Посмотрим теперь на то, что происходит внутри описываемых процессов. В дополнении к элементу управления, который используется для определения конкретного всплывающего элемента, WinJS.UI.SettingsFlyout имеет пару других статических методов, помимо populateSettings: это show и showSettings. Метод show (http://msdn.microsoft.com/library/windows/apps/hh701277.aspx) отображает панель параметров Windows верхнего уровня – то есть - Windows.UI.ApplicationSettings.SettingsPane. Поэтому вы можете видеть, что событие click кнопки "Назад" в вышеприведенной разметке привязано напрямую к методу show, так как нажатие на кнопку "Назад" должно возвратить нас к интерфейсу верхнего уровня.
Примечание. Хотя можно программно вызывать ваши собственные панели параметров, вы не можете сделать этого с командами, которые предоставляет система, наподобие команд "Разрешения" или "Оценки и отзывы". Если вы столкнулись с ситуацией, в которой вам нужно, чтобы пользователь изменил разрешения, например, включил бы определение местоположения, рекомендовано отобразить сообщение об ошибке, предлагающее пользователю сделать это.
Метод showSettings (http://msdn.microsoft.com/library/windows/apps/hh770581.aspx), с другой стороны, показывает конкретный всплывающий элемент настроек, который определен где-то в приложении. Сигнатура метода выглядит как showSettings(<id> [, <page>]) , где <id> идентифицирует всплывающий элемент, который вам нужен, и необязательный параметр <page> указывает на HTML-документ, в котором следует искать всплывающий элемент с заданным <id> , который не найден в текущем документе. Таким образом, showSettings всегда начинает с просмотра текущего объекта document на предмет элемента WinJS.UI.SettingsFlyout, который имеет совпадающее с заданным свойство settingsCommandId или HTML-атрибут id. Если подобный всплывающий элемент найден, он показывается.
Если разметка в предыдущем разделе (с рис. 2.4.) содержится в той же HTML-странице, которая загружена в приложении, следующая строка кода покажет этот всплывающий элемент:
WinJS.UI.SettingsFlyout.showSettings("help");
В подобном случае вы так же можете опустить часть href JSON-объекта, который передается в populateCommands, но только если всплывающий элемент уже содержится в текущем HTML-документе.
Параметр <page>, в свою очередь, позволяет вам разделить всплывающие элементы параметров и остальные страницы приложения. Его значение – это относительный URI, относящийся к пакету приложения. В примере "Параметры приложения" подобный подход используется для помещения всплывающих элементов для каждого сценария в отдельный HTML-файл. Вы так же можете поместить все ваши всплывающие элементы в один HTML-файл, до тех пор, пока они имеют уникальные id. В любом случае, если вы предоставляете параметр <page>, showSettings загрузит код указанного HTML-файла в текущую страницу, используя WinJS.UI.Page.load (который вызовет WinJS.UI.processAll), просматривает полученное дерево DOM на предмет id всплывающего элемента, совпадающего с заданным <id> и показывает его. Если всплывающий элемент найти не удается, вызывается исключение.
Сценарий 5 примера показывает этот способ программной активации элемента. Это так же хороший пример (рис. 2.5.) всплывающего элемента с вертикальной прокруткой:
WinJS.UI.SettingsFlyout.showSettings("defaults", "/html/5-SettingsFlyout-Settings.html");
Рис. 2.5. Всплывающий элемент настроек из Сценария 5 примера "Параметры приложения", показывающий, как всплывающие элементы поддерживают вертикальную прокрутку. Обратите внимание на позицию полосы прокрутки при отображении верхней части элемента (слева), и нижней (справа)
Вызов showSettings, таким образом, это то, что используется в любом обработчике invoked команды, и то, что WinJS выполняет внутри populateCommands. Но это так же означает, что вы можете вызвать showSettings из любого места вашего кода, когда вам нужно показать конкретную панель параметров. Например, если вы столкнулись с ошибкой, с которой можно справиться, изменив параметры приложения, вы можете предоставить в сообщении об этом кнопку, которая вызывает showSettings для открытия конкретной панели. И, если это нужно, метод hide всплывающего элемента может скрыть его. Это не действует на панель параметров верхнего уровня, для скрытия которой нужно использовать Windows.UI.ApplicationSettings.SettingsPane.getForCurrentView.hide.
Вы можете использовать showSettings и hide вместе, на самом деле, если вам нужно организовать перемещение к панелям параметров третьего уровня. Таким образом, одна из ваших собственных панелей параметров может содержать, команду, которая вызывает hide для текущего всплывающего элемента, и затем – showSettings для открытия другого. Кнопка "Назад" этого дополнительного элемента (у них всегда должна быть такая кнопка), похожим образом, вызывает hide для текущего элемента, и showSettings для того, чтобы всплывающий элемент второго уровня снова появился. Тем не менее, мы не рекомендуем делать ваши параметры настолько сложными, чтобы понадобились всплывающие элементы третьего уровня, но такая возможность есть, если у вас есть необходимость в подобном.
Зная о том, как showSettings ищет всплывающий элемент так же полезно, если вы хотите программно создать элемент WinJS.UI.SettingsFlyout. До тех пор, пока подобный элемент управления находится в DOM, когда вы вызываете showSettings с его id, WinJS может найти его и отобразить, как и другие элементы. Подобный подход так же работает, хотя я не пробовал это сделать и не подготовил соответствующего примера, использующего такой гибридный подход. Так как showSettings загружает заданную HTML-страницу как элемент управления страницы с помощью WinJS.UI.Pages.load, эта страница так же может включать собственный скрипт, в котором вы можете задать объект элемента управления страницы с помощью методов вроде processed и ready. В этих методах вы, затем, можете выполнить необходимые настройки всплывающих элементов настроек, заданных в разметке.
Врезка: Изменение разрешений
Обычный вопрос, который связан с параметрами, заключается в том, может ли приложение получить событие, когда пользователь меняет параметры на панели Разрешения. Ответ на этот вопрос отрицательный. Что означает, что вы можете понять, что доступ к какой-то возможности закрыт, либо обрабатывая исключение Access Denied (Доступ запрещен), когда пытаетесь воспользоваться той или иной возможностью. Вам всегда следует обрабатывать ошибки отказа в доступе, так как пользователь может запретить доступ к возможности при первой попытке использования соответствующего API. Когда это происходит, вы отображаете сообщение об отключенных разрешениях (как показано на примере приложения "Here My Am!" в лекции 1) и предоставляете некоторые интерфейсные элементы для выполнения нужной операции. Однако, пользователю все еще нужно самостоятельно активировать команду Разрешения. Дополнительные подробности вы можете узнать в материале "Руководство для устройств, осуществляющих доступ к персональным данным" (http://msdn.microsoft.com/library/windows/apps/Hh768223.aspx).