1

Я работаю над довольно сложным веб-приложением AngularJS и не выполняю работу механизма модальности/маршрутизации, соответствующего моим требованиям.Угловые модалы (ui-router) и концепции общей модальной архитектуры

Ситуация

Мое приложение имеет (упрощенный) следующие лица:

  • Клиенты (имеет 0 или больше Contacts)
  • Заказы (ровно 1 клиента)
  • Контакты (принадлежат точно одному клиенту)

Во время создания нового заказа можно выбрать существующего клиента или создать новый клиент. В процессе создания клиента возможно создание нового контакта.

UI решения/UX

Я смотрел несколько способов, чтобы правильно представлять эту функцию в «не-захламление» и мобильный дружественно. Сначала я старался держаться подальше от модалов или всплывающих окон и пытался создать несколько угловых директив, которые будут отображаться динамически на странице, но это скоро стало слишком сложным. Создание нового клиента существует из нескольких UI-состояний и некоторых подстанций (вкладок) и имеет в нем довольно сложную логику.

Затем я просмотрел отдельные вкладки браузера и общался между ними, используя localStorage. Однако этот подход казался хрупким, а также не очень распространенным для пользователя. Кроме того, пользователь должен продолжить работу на новой вкладке до завершения и только после этого сможет вернуться на предыдущую вкладку. Это невозможно, используя отдельные вкладки браузера.

Я просмотрел всплывающие окна браузера Javascript, но мне тоже не нравится это направление.

С точки зрения пользователя, я считаю, что лучший способ, чтобы использовать модальный диалог, чтобы следить за потоком пользовательского интерфейса:

UI потока

+----------+     +------------+     +-----------+ 
|New Order | - Opens modal -> |New Customer| - Opens modal -> |New Contact| 
+----------+     +------------+     +-----------+ 
    ^       | ^       | 
     |       OK |        OK 
     |  Closes modal and  | |  Closes modal and  | 
     | selects new customer | |  selects new contact  | 
     +----<-----<-------<-----<---+ +----<-----<-------<-----<----+ 

Примечание: новый клиент и Новый Контактные состояния также являются состояниями, которые можно открыть в обычном окне.

Я создал маршруты Угловое-UI-маршрутизатор, как:

  • New Order: app.orders.new
  • Новый Заказчик: app.customers.new
  • Новый Контакт: app.contacts.новый

Разработка

Для поддержки множественного архитектуры модальный Я пытался несколько вещей:

  1. Использование Angular UI Bootstrap Modal
  2. Использование UI-Router-Extras способом, используя собственные встроенные Модальные окна

Некоторые важные аспекты, о которых следует помнить:

  • Мне не нужен прямой URL-адрес, чтобы указать прямо на модальное окно. URL-адрес может оставаться в статусе «Новый клиент».
  • Поведение должно быть Модальным, поэтому не может работать над родительским окном.
  • Он должен иметь возможность открывать и показывать несколько состояний друг за другом (например, мастер в одном модуле)
  • Несколько модалов, открытых в определенном порядке, должны быть закрыты в том же порядке. (Последний, первым обслужен)

1. Использование Angular UI Bootstrap Modal Таким образом, казалось многообещающим. Я создал отдельный маршрутизации, которые используют некоторые контроллеры и виды на регулярных маршрутах:

  • Modal.Customers.New
  • Modal.Contacts.New

Но, к сожалению, я изо всех сил, чтобы открыть больше модалов внутри модального и сохранить состояние предыдущего модального. Я использовал UI-Router-Extras Sticky States, чтобы сохранить фоновое состояние. Однако, как указывает UI-Router-Extras, Sticky States работает только тогда, когда у каждого штата есть собственный ui-view. Ui-view должен быть объявлен заранее. Это невозможно, потому что теоретически пользователь может открыть неограниченное количество вложенных модалов в моем приложении.

2. Использование UI-Router-Extras способа использования собственных встроенных модальных окон

Я попытался создать простую модальность в смене углового UI модального с помощью простого модальных примера UI-маршрутизатора Дополнительно, как в:

Но, к сожалению, у меня такая же проблема, как с вариантом 1. Проблема заключается в том, что состояния и маршрутизация становятся слишком сложными, когда модалы вложены.

Решение

Я действительно изо всех сил о том, что это лучший подход в настоящее время. Я думаю о показе Модального окна оверлея с iframe в нем, которые открывают отдельный маршрут UI-Router, например: Modal.Customers.New, который показывает только содержимое приложения (а не строки меню и т. Д.).

При использовании iframe я могу сохранить отдельную информацию о маршрутах и ​​состояниях, доступных в родительском окне и в iframe. Мне нужно выполнить некоторые пользовательские javascript для поддержки масштабирования iframes в правильном формате, но это приемлемо.

Но он по-прежнему чувствует себя «взломанным» решением.

Я хотел бы услышать ваши решения и идеи.

ответ

0

В конце концов я пошел на комбинацию использования iframe с Угловыми пользовательскими интерфейсами. Этот подход дал мне полную гибкость в использовании сложных маршрутов в моем приложении и в моделях экранов Angular UI, которые автоматически изменяют размер iframe на разных разрешениях экрана.

Я создал маршруты для всех состояний, используемых в модалях с префиксом: modal. вместо приложения. Таким образом, я мог использовать только субстрат «content» на странице, чтобы показать внутри Modal и все еще иметь полное повторное использование исходных контроллеров и представлений.

Единственный сложный бит - это когда несколько вложенных модалов открыты. Там я должен был проверить, был ли я в модальном или в обычном состоянии. Это было довольно легко, используя имя состояния:

IsModal() { 
    return this.$state.current.name.indexOf("modal") == 0; 
} 

На корневом фрейме (не-модальный вид) Я собрал всю открытую угловые UI модальности в массиве и проверить на открытие нового модальности, если модальное был на корень представлений (немодальный). Если нет, то я пересек вверх IFRAME в родительской области с использованием:

var parentScopeModalService = (<any>parent).angular.element(window.frameElement).scope().MyModalService; 

Это на самом деле работает довольно хорошо, потому что все фреймы находятся на том же домене.