【问题标题】:Get polymer parent element获取聚合物父元素
【发布时间】:2015-03-11 04:55:15
【问题描述】:

所以我已经使用 Polymer 大约一天了,但我在表达这个问题时遇到了困难,所以如果我的方法偏离了基础,请不要觉得有必要解决这个问题,而是指出我正确的方向。

我拥有的是自定义元素中的自定义元素,我希望子元素能够影响父元素的属性。我采用的方法是创建一个单击处理程序,关闭 IIFE 中的父元素,然后将该处理程序传递给子组件。就这样……

Polymer({
  ready: function(){
     this.superHandler = (function(p) {
        return function() {
          // "this" here will be the sub-component
          p.title = this.title;
        }
     })(this);
  }
});

父元素在它的模板中使用它的地方...

<polymer-element name="parent-element">
  <template>
    <sub-element on-click={{superHandler}} />
  </template>
</polymer-element>

这(在我的真实代码中,虽然这里可能存在拼写错误)适用于除 IE 之外的所有东西,而且我知道 IE 不受官方支持,但它是如此接近,我不想放弃它。我要避免的事情是重复引用 parentNodes 和 shadowRoots 以到达我正在寻找的父级。

编辑

我忘了提到它在 IE 中是如何失败的,以及为什么我想避免调用 parentNode。在 IE 中,当它去派发事件具体到 polymer.js 的第 9131 行时,变量 "method" 和 obj[method] 中的引用是 IE 中的字符串,因此没有方法适用。我想避免使用 parentNode 的原因是因为调用者不是直接父节点,所以我不想在找到正确的父节点之前一直获取 parentNodes,因为当我可以命名变量时代码更容易理解。

编辑 2

我现在要做的是(因为它在 IE9 中工作),尽管我将问题留待更好的答案是继续使用 IIFE,返回一个函数,该函数接受一个子参数。然后孩子将通过查询选择器找到感兴趣的父母。这意味着孩子必须对父母和调用方法有先见之明,这并不理想,但是... IE。

所以父级将其设置为...

Polymer('parent-element', {
  ready: function(){
     this.superHandler = (function(p) {
        return function(child) {
          p.title = chile.title;
        }
     })(this);
  }
});

并且孩子必须通过查询选择器获取它,例如通过“父元素”并知道名称“superHandler”(不是实际名称)

Polymer('child-element',{
        clickHandler: function(){
            var p = document.querySelector('parent-element').superHandler;
            p(this);
        }
    });

更好的想法?

【问题讨论】:

  • 不确定用例是什么,但是请注意,如果您将父级的已发布属性向下传递给子级,那么如果子级修改了该属性,则父级的 attributeChanged 函数(如果您在place) 会被自动调用

标签: javascript polymer


【解决方案1】:

您可以使用自己的事件在元素之间传递数据。

父组件:

<polymer-element name="parent-element">
  <template>
    <!-- ... -->
    <sub-element></sub-element>
  </template>
  <script>
  Polymer({
    ready: function() {
      this.addEventListener('eventFromChild', this.myAction);
    },
    myAction: function(event) {
      console.log(event.detail);
    },
  });
  </script>

子组件:

<polymer-element name="sub-element" attributes="foo bar">
  <template>
    <!-- ... -->
    <button on-click="{{passParams}}">Send</button>
  </template>
  <script>
  Polymer({
    ready: function() {
      this.foo = 'abc';
      this.bar = '123';
    },
    passParams: function() {
      this.fire('eventFromChild', { foo: this.foo, bar: this.bar });
    },
  });
</script>

【讨论】:

    【解决方案2】:

    这是一种在 Javascript 中访问父元素的简单方法。这适用于a personal work(聚合物 0.5 - 如 cmets 中所述,1.0 中的情况有所不同)。没有在 IE 上测试,但在我看来这是一个简单的解决方案:

    Polymer('sub-element', {
      ready: function(){
         this.parentNode;
      }
    });
    

    【讨论】:

    • 在我的项目中,this.parentNode 不能在聚合物中工作,因为我是影子 DOM 的根。要访问组件父级,我必须使用:this.host.parentNode
    • 在 Polymer 1.0 中 this.parentNode 将获取父 Web 组件。
    • 在 Polymer 1.0 中 this.parentNode 没有获取父 Web 组件。假设您的子 Web 组件包含在

      中。您将获得一个

      作为父节点。似乎不可能有一个通用的方法来做到这一点。冒泡事件可能是以一般方式进行交流的唯一方式。

    【解决方案3】:

    感谢您提供自定义活动建议。这让我回过头来再次查看核心元素以找到this

    那我只需要添加一个

    <core-signals on-core-signal-my-event="{{myEventHandler}}"></core-signals>
    

    触发一个名为(在本例中)“my-event”的“core-signal”事件,并在父对象上创建一个方法“myEventHandler”,例如

    Polymer({
      myEventHandler: function(e,detail,sender) {...}
    })
    

    【讨论】:

    • 在 Polymer 1.0 中,核心信号被重命名为铁信号。另请注意(从 Iron-signals 文档复制):只要您可以使用控制器(父元素)来代替通信,请避免使用 Iron-signals。
    【解决方案4】:

    由于组件的性质,我很犹豫以这种方式访问​​ parentNode。如果您需要样式,可以使用:host() css 规则来完成。恕我直言,除非你有充分的理由,否则接触父元素似乎很讨厌。为什么不使用自定义事件或像localStorage 这样的中间存储?

    还可以查看"The 'Gold Standard' Checklist for Web Components" 以获取有关最佳实践的更多帮助。

    【讨论】:

    • 无论如何,这只是一个很棒的清单。感谢您的链接,是的,我同意自定义事件是要走的路。一旦我开始向下传递函数的路径,我就被固定了。
    • 非常酷的菲利克斯。那么我们觉得这些答案之一是正确的吗?还是我们需要更多的测试?让我知道我是否可以提供进一步的帮助。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-06
    • 2015-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多