Как я могу поместить диалоговое окно Angular Material panel относительно кнопки?
В соответствии с обсуждением в Github нельзя установить стандартный диалог (api), но диалоговые окна панели (api) могут позиционироваться.
A упрощенная демонстрация показывает, что это верно:
var position = this._mdPanel.newPanelPosition().bottom(0).right(0);
Angular Документы по материалам показывают метод, который позволяет позиционировать относительно элемента с щелчком (или любого другого). Однако я не могу заставить это работать.
var target = el.target;
var position = this._mdPanel.newPanelPosition().relativeTo(target);
Передача жестких значений для .top()
и .right()
, например, позволяет позиционировать относительно окна просмотра. Тем не менее, я не могу установить позиционирование относительно элемента с щелчком. Как это должно работать?
Ответы
Ответ 1
Я работаю с Angular Материалом в течение последних нескольких месяцев и все еще не могу найти документацию, поэтому прошу простить длину этого сообщения как мою псевдо-документацию по этой проблеме. Но вот что я знаю:
Мне удалось получить расположение панели по отношению к целевому элементу, привязав функцию addPanelPosition
к функции relativeTo
как таковой:
var position = this._mdPanel
.newPanelPosition()
.relativeTo(ev.target)
.addPanelPosition('align-start', 'below') // or other values
(в этом случае ev
- объект события $, прошедший через ng-click)
Мне удалось найти приемлемые параметры для addPanelPosition
, и они следующие:
Позиция панели y принимает только следующие значения: центр | выравнивающие вершины | выравнивающие днища | выше | ниже
Панель x Позиция принимает только следующие значения: центр | align-start | выравнивание | офсет-старт | Смещение конца
Довольно интересно, в демонстрации Angular Material они используют свойства this._mdPanel.xPosition.ALIGN_START
и this._mdPanel.yPosition.BELOW
, которые просто разрешают строки как их значения x и y для функции addPanelPosition
. Я всегда прятался со строковыми значениями. Однако использование строковых значений может быть проблематичным, если разработка этой функции все еще находится в движении, и они изменяют допустимые строковые значения.
Я укажу еще одну проблему, которую я видел.
Другим трюком, который они используют в демо, является указание имени класса в функции relativeTo
вместо целевого элемента, а затем помещайте этот класс в сам целевой элемент. Причина, по которой этот подход может быть полезен, состоит в том, что объект $event из ng-click может предоставлять разные целевые элементы на основе того, что именно было нажато. Например, нажатие кнопки <div>
даст другую цель, чем щелчок на тексте <span>
внутри кнопки. Это приведет к тому, что ваша панель сдвинет места, если вы не предоставите дополнительную функциональность, чтобы этого не сделать.
Codepen
Я взял их демо и действительно сократил его до размера, чтобы сосредоточиться на этой проблеме. Вы можете увидеть обновленный код здесь
Ответ 2
Как я размещаю в комментарии, здесь вы можете видеть, как он работает над плункером.
Мое решение очень близко к @Я думаю, что могу ответить на код. Тем не менее, в моем ответе вместо меню отображается <md-dialog>
, когда кнопка нажата, как она запросила в OP.
Помимо рабочего плунжера с диалогом, нет ничего, что можно добавить к хорошему @Я думаю, что могу ответить на код. Как показано в демонстрации angular -материала md-panel, здесь нужно установить положение панели относительно кнопки. Чтобы сделать это (например, в демонстрации angular -материал), мы можем использовать определенный класс css (demo-dialog-open-button
в моем примере), чтобы найти целевой элемент. это сложная вещь, на мой взгляд... но она хорошо работает для этого случая использования (это также хорошо объяснено в другом ответе).
Код для справки, см. plunker для получения полной информации:
html (обратите внимание, что класс css добавлен к кнопке):
<md-button class="md-primary md-raised demo-dialog-open-button" ng-click="ctrl.showDialog($event)">
Dialog
</md-button>
JS.
var position = this._mdPanel.newPanelPosition()
.relativeTo('.demo-dialog-open-button')
.addPanelPosition(this._mdPanel.xPosition.ALIGN_START, this._mdPanel.yPosition.BELOW);
Надеюсь, что это поможет
Ответ 3
Диалоги - очень простые виджеты. Основное внимание уделяется самой сложной вещи. Мне больно, что ваш вопрос превратился в такой сложный процесс.
Просто, чтобы указать на очевидное, у вас есть полный контроль над позиционированием любого отдельного диалога благодаря настроенному имени класса.
.demo-dialog-example {
top: 20px;
left: 20px;
}
Также, в вашем методе showDialog, почему бы не настроить обратный вызов через обещание открытого метода? Что-то вроде:
this._mdPanel.open(config).then(function() {
var dialog = angular.element(document.querySelector('.demo-dialog-example'));
//Centering, positioning relative to target, or draggable logic goes here
});
Я уважаю, что вы пытаетесь улучшить логику плагина и делать вещи "Angular", но эти относительно простые требования не должны вызывать у вас столько страданий.