如何相对于按钮定位 Angular Material 面板对话框?
How can I position an Angular Material panel dialog relative to a button?
按照discussion at Github one cannot position a standard dialog (api), but panel dialogs (api)即可定位。
一个simplified demo表明这是真的:
var position = this._mdPanel.newPanelPosition().bottom(0).right(0);
Angular Material docs 显示了一种允许相对于单击的元素(或传入的任何内容)进行定位的方法。但是,我无法使它正常工作。
var target = el.target;
var position = this._mdPanel.newPanelPosition().relativeTo(target);
例如,为 .top()
和 .right()
传递硬值,允许相对于视口定位。不过,我无法获得相对于单击元素的定位。这应该如何工作?
过去几个月我一直在使用 Angular Material,但仍然发现缺少文档,所以请原谅这个 post 作为我关于这个问题的伪文档的长度。但这是我所知道的:
我只能通过将 addPanelPosition
函数链接到 relativeTo
函数来使面板位置相对于目标元素起作用:
var position = this._mdPanel
.newPanelPosition()
.relativeTo(ev.target)
.addPanelPosition('align-start', 'below') // or other values
(在本例中,ev
是ng-click传递的$event对象)
我能够找到 addPanelPosition
可接受的参数,它们如下:
Panel y position only accepts the following values:
center | align-tops | align-bottoms | above | below
Panel x Position only accepts the following values:
center | align-start | align-end | offset-start | offset-end
有趣的是,在 Angular Material 演示中,他们使用 this._mdPanel.xPosition.ALIGN_START
和 this._mdPanel.yPosition.BELOW
属性,这些属性简单地解析为字符串作为 addPanelPosition
的 x 和 y 值功能。我总是直接使用字符串值。但是,如果此功能的开发仍在不断变化并且它们更改了可接受的字符串值,则使用字符串值可能会出现问题。
我再指出一个我看到的问题。
他们在演示中使用的另一个技巧是在 relativeTo
函数中指定一个 class 名称而不是目标元素,然后将该 class 放在目标元素本身上。这种方法之所以有用,是因为来自 ng-click 的 $event 对象可以根据所点击的内容提供不同的目标元素。例如,单击按钮 <div>
将提供与单击按钮内的 <span>
文本不同的目标。这将导致您的面板移动位置,除非您提供不这样做的附加功能。
Codepen
我拿了他们的演示并将其真正缩小以专注于这个问题。可以看到更新后的codepenhere
对话框是非常简单的小部件。捕捉焦点是他们所做的最复杂的事情。你的问题演变成这么复杂让我很痛苦。
显而易见的是,由于您配置的 class 名称,您确实可以完全控制定位任何单个对话框。
.demo-dialog-example {
top: 20px;
left: 20px;
}
此外,在您的 showDialog 方法中,为什么不通过 open 方法的承诺设置回调?类似于:
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 way",但是这些相对简单的要求不应该让您如此心痛。
正如我在评论中 post,here 你可以看到它在 plunker 上工作。
我的解决方案非常接近@I think I can code answer。但是,在我的回答中,单击按钮时显示的不是菜单,而是 <md-dialog>
,正如 OP 中所要求的那样。
除了带有对话框的工作插件之外,没有什么可以添加到好的@I think I can code answer。如angular-materialmd-panel demo所示,这里的关键是设置面板相对于按钮的位置。为此(就像在 angular-material 演示中一样),我们可以使用特定的 css class(在我的示例中为 demo-dialog-open-button
)来查找目标元素。在我看来这是一件棘手的事情......但它适用于这个用例(在另一个答案中也有很好的解释)。
参考代码,完整详情见plunker:
html(注意添加到按钮的cssclass):
<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);
希望对您有所帮助
按照discussion at Github one cannot position a standard dialog (api), but panel dialogs (api)即可定位。
一个simplified demo表明这是真的:
var position = this._mdPanel.newPanelPosition().bottom(0).right(0);
Angular Material docs 显示了一种允许相对于单击的元素(或传入的任何内容)进行定位的方法。但是,我无法使它正常工作。
var target = el.target;
var position = this._mdPanel.newPanelPosition().relativeTo(target);
例如,为 .top()
和 .right()
传递硬值,允许相对于视口定位。不过,我无法获得相对于单击元素的定位。这应该如何工作?
过去几个月我一直在使用 Angular Material,但仍然发现缺少文档,所以请原谅这个 post 作为我关于这个问题的伪文档的长度。但这是我所知道的:
我只能通过将 addPanelPosition
函数链接到 relativeTo
函数来使面板位置相对于目标元素起作用:
var position = this._mdPanel
.newPanelPosition()
.relativeTo(ev.target)
.addPanelPosition('align-start', 'below') // or other values
(在本例中,ev
是ng-click传递的$event对象)
我能够找到 addPanelPosition
可接受的参数,它们如下:
Panel y position only accepts the following values: center | align-tops | align-bottoms | above | below
Panel x Position only accepts the following values: center | align-start | align-end | offset-start | offset-end
有趣的是,在 Angular Material 演示中,他们使用 this._mdPanel.xPosition.ALIGN_START
和 this._mdPanel.yPosition.BELOW
属性,这些属性简单地解析为字符串作为 addPanelPosition
的 x 和 y 值功能。我总是直接使用字符串值。但是,如果此功能的开发仍在不断变化并且它们更改了可接受的字符串值,则使用字符串值可能会出现问题。
我再指出一个我看到的问题。
他们在演示中使用的另一个技巧是在 relativeTo
函数中指定一个 class 名称而不是目标元素,然后将该 class 放在目标元素本身上。这种方法之所以有用,是因为来自 ng-click 的 $event 对象可以根据所点击的内容提供不同的目标元素。例如,单击按钮 <div>
将提供与单击按钮内的 <span>
文本不同的目标。这将导致您的面板移动位置,除非您提供不这样做的附加功能。
Codepen
我拿了他们的演示并将其真正缩小以专注于这个问题。可以看到更新后的codepenhere
对话框是非常简单的小部件。捕捉焦点是他们所做的最复杂的事情。你的问题演变成这么复杂让我很痛苦。
显而易见的是,由于您配置的 class 名称,您确实可以完全控制定位任何单个对话框。
.demo-dialog-example {
top: 20px;
left: 20px;
}
此外,在您的 showDialog 方法中,为什么不通过 open 方法的承诺设置回调?类似于:
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 way",但是这些相对简单的要求不应该让您如此心痛。
正如我在评论中 post,here 你可以看到它在 plunker 上工作。
我的解决方案非常接近@I think I can code answer。但是,在我的回答中,单击按钮时显示的不是菜单,而是 <md-dialog>
,正如 OP 中所要求的那样。
除了带有对话框的工作插件之外,没有什么可以添加到好的@I think I can code answer。如angular-materialmd-panel demo所示,这里的关键是设置面板相对于按钮的位置。为此(就像在 angular-material 演示中一样),我们可以使用特定的 css class(在我的示例中为 demo-dialog-open-button
)来查找目标元素。在我看来这是一件棘手的事情......但它适用于这个用例(在另一个答案中也有很好的解释)。
参考代码,完整详情见plunker:
html(注意添加到按钮的cssclass):
<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);
希望对您有所帮助