如何分离 Polymer 按钮和对话框

How to separate Polymer button and dialog

在聚合物对话框演示中,他们有这样的代码:

 <script src=
https://github.com/webcomponents/webcomponentsjs/blob/master/webcomponents.js>
<link rel="import" href="https://github.com/Polymer/polymer/blob/master/polymer.html">

<link rel="import" href="https://github.com/PolymerElements/paper-button/blob/master/paper-button.html">
<link rel="import" href="https://github.com/PolymerElements/paper-dialog/blob/master/paper-dialog.html">

<section onclick="clickHandler(event)">
  <h4>Transitions</h4>
  <paper-button data-dialog="animated">transitions</paper-button>
  <paper-dialog id="animated" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop>
    <h2>Dialog Title</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
      dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  </paper-dialog>
</section>

<script>
  function clickHandler(e) {
    var button = e.target;
    while (!button.hasAttribute('data-dialog') && button !== document.body) {
      button = button.parentElement;
    }

    if (!button.hasAttribute('data-dialog')) {
      return;
    }

    var id = button.getAttribute('data-dialog');
    var dialog = document.getElementById(id);
    if (dialog) {
      dialog.open();
    }
  }
</script>

我想将按钮(在我的例子中是 fab)和对话框包装到我自己的独立 Web 组件中。

我创建了一个对话框按钮,试图包装按钮和事件:

<paper-fab class="addbutton" icon="add" onclick="clickHandler(event)"></paper-fab>

</template>
<script>
  Polymer({
    is: 'my-dialog-button',
    properties: {

      dialog_id: {
        type: String
      },

    }
  })


  function clickHandler(e) {

    var button = e.target;
    while (!button.hasAttribute('dialog_id') && button !== document.body) {
      button = button.parentElement;
    }

    if (!button.hasAttribute('dialog_id')) {
      console.log("you have no element with 'dialog_id' defined")
      return;
    }


    var id = button.getAttribute('dialog_id');
    console.log("dialog " + id + " requested")
    var dialog = document.getElementById(id);
    if (dialog) {

      dialog.open();
    } else {
      console.log("dialog " + id + " does not exist")
    }
  }
</script>

这让我可以执行以下操作:

<thor-dialog-button dialog_id="add-button"></thor-dialog-button>
<paper-dialog id="add-button">
  <h2>"Hello"</h2>
  <p>"World"</p>
</paper-dialog>

然而,一旦我将对话框包装在它自己的组件中,"id" 在那个 dom 上下文中就不再可用。所以没用。

我认为 ID 方法并没有真正起作用,我需要将对话框 "open" 绑定到按钮 "onclick" 但我不知道该怎么做,我发现:

https://www.polymer-project.org/1.0/docs/devguide/templates.html

但我不确定如何将其应用于包装元素(或者至少到目前为止我在该方法上失败了)。

总而言之,分离 2 个包装的 Web 组件的正确方法是什么?它会是什么样子?

您想要两个元素 my-dialog-buttonmy-dialog。您的按钮元素需要重新设计。我们需要将 clickHandler 函数移到 Polymer({ }) 块中。还建议使用 on-tap 事件而不是 on-clickon-tap 在桌面和移动设备上实现更一致的体验。

<script>
Polymer({
  is: 'my-dialog-button',
  properties: {

    dialogId: {
      type: String
    }
  },

  clickHandler: function (e) {
    var button = e.target;
    while (!button.hasAttribute('dialogId') && button !== document.body) {
      button = button.parentElement;
    }

    if (!button.hasAttribute('dialogId')) {
      console.log("you have no element with 'dialogId' defined");
      return;
    }


    var id = button.getAttribute('dialogId');
    console.log("dialog " + id + " requested");
    var dialog = document.getElementById(id);
    if (dialog) {

      dialog.open();
    }
    else
    {
      console.log("dialog " + id + " does not exist")
    }
  }
});

像那样。聚合物中的主要内容之一是将所有 javascript 保留在 Polymer({ }) 块内。这样你就可以利用聚合物的所有好处,而不是 运行 像这个问题那样陷入范围界定问题。

尝试将对话框包装到另一个元素时问题仍然存在。由于元素的作用域,您无法再访问 dialog.open() 方法。 dialog.open() 只能在 my-dialog 元素内访问。要解决这个问题,您需要实现自己的 .open() 方法。代码看起来像这样:

<template>
  <paper-dialog id="dialog">
   //Your dialog content
  </paper-dialog>
</template>

<script>
  Polymer({
    is: 'my-dialog',

    open: function(){
      this.$.dialog.open();
    }
  });
</script>

它在您的索引或您使用它的其他元素中的样子。

<my-dialog-button dialog-id="testdialog"></my-dialog-button>
<my-dialog id="testdialog"></my-dialog>

这样您就可以在 my-dialog 元素内打开对话框。

工作示例:

<!doctype html>

<head>
  <meta charset="utf-8">
  <!---- >
  <base href="https://polygit.org/components/">
  Toggle below/above as backup when server is down
  <!---->
  <base href="https://polygit2.appspot.com/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link href="polymer/polymer.html" rel="import">
  <link href="paper-fab/paper-fab.html" rel="import">
  <link href="paper-dialog/paper-dialog.html" rel="import">
</head>

<body>

  <dom-module id="my-dialog-button">

    <style>
      paper-fab.addbutton {
        position: absolute;
        right: -27px;
        top: 34px;
      }
    </style>
    <template>
      <paper-fab class="addbutton" icon="add" on-tap="clickHandler"></paper-fab>
    </template>
    <script>
      Polymer({
        is: 'my-dialog-button',
        properties: {

          dialogId: {
            type: String
          }
        },

        clickHandler: function(e) {
          var button = e.target;
          while (!button.hasAttribute('dialogId') && button !== document.body) {
            button = button.parentElement;
          }

          if (!button.hasAttribute('dialogId')) {
            console.log("you have no element with 'dialogId' defined");
            return;
          }


          var id = button.getAttribute('dialogId');
          console.log("dialog " + id + " requested");
          var dialog = document.getElementById(id);
          if (dialog) {

            dialog.open();
          } else {
            console.log("dialog " + id + " does not exist")
          }
        }
      });
    </script>

  </dom-module>

  <!--- ---------------------------------------------my dialog------------------------------------------------>


  <dom-module id="my-dialog">

    <template>
      <paper-dialog id="dialog">
        <h2>"hello world"</h2>
        <p>"I am bob"</p>
      </paper-dialog>
    </template>

    <script>
      Polymer({
        is: 'my-dialog',

        open: function() {
          this.$.dialog.open();
        }
      });
    </script>


  </dom-module>

  <!-----------------------------page--------------------------------------->
  <my-dialog-button dialogId="add-button"></my-dialog-button>
  <my-dialog id="add-button"></my-dialog>


</body>


旁注:

编写聚合物元素时,您不需要在 Polymer({ }); 之外声明任何 javascript 代码。如果您在该块之外声明代码,则项目内部的范围界定可能会混乱。