如何相对于按钮定位Angular Material面板对话框?

时间:2016-08-15 18:54:03

标签: javascript angularjs modal-dialog panel angular-material

根据discussion at Github,无法定位standard dialogapi),但可以定位panel dialogsapi)。

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()的硬值允许相对于视口进行定位。但是,我无法相对于被点击的元素进行定位。这应该如何运作?

3 个答案:

答案 0 :(得分:5)

过去几个月我一直在使用Angular Material,但仍然发现文档缺乏,所以请原谅这篇文章的长度作为我关于这个问题的伪文档。但这就是我所知道的:

我只能通过将addPanelPosition函数链接到relativeTo函数来使相对于目标元素的面板位置工作:

var position = this._mdPanel
  .newPanelPosition()
  .relativeTo(ev.target)
  .addPanelPosition('align-start', 'below') // or other values

(在这种情况下,ev是ng-click传递的$ event对象)

我能够追踪addPanelPosition的可接受参数,它们如下:

  

面板y位置仅接受以下值:       中心| align-tops |对齐底部|以上|以下

     

面板x位置仅接受以下值:       中心| align-start | align-end | offset-start |偏移端

足够多,在Angular Material演示中,他们使用this._mdPanel.xPosition.ALIGN_STARTthis._mdPanel.yPosition.BELOW属性,这些属性只是将字符串解析为addPanelPosition函数的x和y值。我总是直接使用字符串值。但是,如果此功能的开发仍在不断变化并且它们会更改可接受的字符串值,则使用字符串值可能会出现问题。

我会指出我见过的另一个问题。

他们在演示中使用的另一个技巧是在relativeTo函数中指定一个类名而不是目标元素,然后将该类放在目标元素本身上。这种方法有用的原因是因为来自ng-click的$ event对象可以根据点击的确切内容提供不同的目标元素。例如,单击按钮<div>将提供与单击按钮内的<span>文本不同的目标。这将导致您的面板移动位置,除非您提供不这样做的附加功能。

<强> Codepen

我拿了他们的演示并真正缩小尺寸以专注于这个问题。您可以看到更新的代码集here

答案 1 :(得分:1)

当我在评论中发帖here时,你可以看到它在一个傻瓜上工作。

我的解决方案非常接近@I我想我可以编码答案。但是,在我的回答中,单击按钮时会显示demo-dialog-open-button而不是菜单,因为它是在OP中请求的。

除了带有对话框的工作人员,没有太多可以添加到好的@I我想我可以编码答案。正如它在角度材料md-panel demo中所示,这里的关键是设置面板相对于按钮的位置。要做到这一点(比如在角度材质演示中),我们可以使用特定的css类(在我的示例中为<md-button class="md-primary md-raised demo-dialog-open-button" ng-click="ctrl.showDialog($event)"> Dialog </md-button> )来查找目标元素。在我看来,这是一个棘手的事情......但它适用于这个用例(在另一个答案中也很好地解释了)。

参考代码,有关详细信息,请参阅plunker

html (请注意添加到按钮的css类):

var position = this._mdPanel.newPanelPosition()
      .relativeTo('.demo-dialog-open-button')
      .addPanelPosition(this._mdPanel.xPosition.ALIGN_START, this._mdPanel.yPosition.BELOW);

JS 控制器。

{{1}}

希望有所帮助

答案 2 :(得分:0)

对话框是非常简单的小部件。诱捕焦点是他们所做的最复杂的事情。我很痛苦你的问题已演变成如此复杂的问题。

只是说明显而易见,由于您配置的类名,您可以完全控制任何单个对话框的定位。

.demo-dialog-example {
    top: 20px;
    left: 20px;
}

另外,在showDialog方法中,为什么不通过open方法的promise来设置回调?类似的东西:

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
});

我尊重您正在尝试改进插件的逻辑并按照“角度方式”进行操作,但这些相对简单的要求不应该让您心痛。