【问题标题】:How can I position an Angular Material panel dialog relative to a button?如何相对于按钮定位 Angular Material 面板对话框?
【发布时间】:2016-12-22 00:27:01
【问题描述】:

根据discussion at Github,无法定位standard dialog (api),但可以定位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() 的硬值允许相对于视口进行定位。不过,我无法获得相对于单击元素的定位。这应该如何工作?

【问题讨论】:

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


    【解决方案1】:

    过去几个月我一直在使用 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 位置仅接受以下值: 中心 |对齐顶部 |对齐底部 |以上 |下面

    面板 x 位置仅接受以下值: 中心 |对齐开始 |对齐端 |偏移开始 |偏移端

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

    我会再指出一个我看到的问题。

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

    Codepen

    我接受了他们的演示并真正将其缩小以专注于这个问题。可以看到更新的codepenhere

    【讨论】:

      【解决方案2】:

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

      我的解决方案非常接近@我想我可以编写答案。但是,在我的回答中,当单击按钮时,会显示 <md-dialog> 而不是菜单,正如 OP 中所要求的那样。

      除了带有对话框的工作插件之外,没有什么可以添加到好的@我想我可以编写答案。如 angular-material md-panel demo 所示,这里的关键是设置面板相对于按钮的位置。为此(如在 angular-material 演示中),我们可以使用特定的 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 方法中,为什么不通过 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
        });
        

        我尊重您正在尝试改进插件的逻辑并以“Angular 方式”做事,但这些相对简单的要求不应该让您如此心痛。

        【讨论】:

        • 我同意,但我担心固定的 CSS 定位不是一个理想的解决方案。我读到的内容表明定位可以动态发生。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-01
        • 2010-10-31
        • 1970-01-01
        • 1970-01-01
        • 2017-04-05
        • 1970-01-01
        相关资源
        最近更新 更多