【问题标题】:Polymer elements: Fire event from child element to parent, then push values into array attribute聚合物元素:从子元素触发事件到父元素,然后将值推送到数组属性中
【发布时间】:2015-02-20 15:20:57
【问题描述】:

我制作了这个自定义元素(request-form),其中包含一系列元素(自定义输入)。 request-form 有一个 formvalues 属性,是一个数组。

我的目标是每次更改自定义输入值时,都应将其新值推送到请求表单数组中。

<polymer-element name="request-form" attributes="isSearch formvalues">
<template>
    <style>
    </style>
    <div layout vertical>
        <custom-core-input 
            columnId="12345678-1234-1234-123456789123"
            validation="^[0-9]*$" 
            inputRequired
            on-inputcommited="{{getinput}}">
        </custom-core-input>
        [... some more custom-core-inputs ...]
    </div>        
</template>
<script>
    Polymer({
        created: function () {
            this.formvalues = [];
        },
        getinput: function (e, detail, sender) {
            this.formvalues.push(detail.columnid + "|" + detail.inputval);
        }
    });
</script>

这是我的自定义输入元素中输入字段 (id="custominput") 上的值发生变化时的代码。

inputCommited: function () {
            this.$.decorator.isInvalid = !this.$.custominput.validity.valid;
            if (this.$.custominput.validity.valid) {
                var inputval = this.$.custominput.value;
                this.fire('inputcommited', { inputval: inputval, columnid: this.columnId });
            }
        }

更改输入的值会触发此函数,检查其有效性和所有内容,但不会触发父元素的 getinput 函数。

最后,我想要的是一个字符串数组,例如 {"columnid1|value1", "columnid2|value2", [...]}

编辑

在周围插入几个警报后,我可以肯定地说子元素中的 inputCommited 工作正常,它运行所有代码,在 'this.fire(...)' 语句之前和之后。

永远不要使用 getinput 中的代码

编辑

嗯,这是我正在尝试做的一个工作示例,取自他们网页上显示的聚合物示例/教程。

首先是这个明信片元素,里面有两个图标:

<polymer-element name="post-card">
   <template>
      <style>
      [...]
      </style>
      [...]
      <core-icon-button
          id="favicon"
          icon="favorite"
          on-tap="{{favoriteTapped}}">
      </core-icon-button>

      <core-icon-button
          id="banicon"
          icon="remove-circle"
          on-tap="{{bannedTapped}}">
      </core-icon-button>
  </template>
  <script>
  Polymer({
      publish: {
          favorite: {
              value: false,
              reflect: true
          },
          banned: {
              value: false,
              reflect: true
          }
      },
      favoriteTapped: function (event, detail, sender) {
          this.favorite = !this.favorite;
          this.banned = false;
          this.fire('favorite-tap');
      },
      bannedTapped: function (event, detail, sender) {
          this.banned = !this.banned;
          this.favorite = false;
          this.fire('banned-tap');
      }
  });
 </script>
 </polymer-element>

如您所见,每当点击两个图标之一时,代码都会告诉它触发和事件、禁止点击或收藏夹

现在,这是父元素,post-list:

<polymer-element name="post-list" attributes="show">
 <template>
 <style>
 [...]
 </style>

<post-service id="service" posts="{{posts}}"></post-service>

<div layout vertical center>
  <template repeat="{{post in posts}}">
    <post-card
      favorite="{{post.favorite}}"          
      on-favorite-tap="{{handleFavorite}}" 
      banned="{{post.banned}}"
      on-banned-tap="{{handleBanned}}">
      [...]
    </post-card>
  </template>
</div>
</template>

<script>
  Polymer({
      handleFavorite: function (event, detail, sender) {
          var post = sender.templateInstance.model.post;
          this.$.service.setFavorite(post.uid, post.favorite);
      },
      handleBanned: function (event, detail, sender) {
          var post = sender.templateInstance.model.post;
          this.$.service.setBanned(post.uid, post.banned);
      }
  });
</script>
</polymer-element>

banned-tap 和 favorite-tap 都会触发父事件,正如我所愿,设置 on-whatever="{{dosomething}}"

【问题讨论】:

  • 我找不到“inputcommited”事件的文档?!您是否尝试过使用 'change' 事件,例如: on-change="{{getinput}}" ?
  • 嗯,让我们看看,据我所知:我的输入有事件 on-change,它触发了 inputCommited 的事情(第二个代码片段)。所以我告诉输入,一旦 inputCommited 被触发,如果它有效,那么它必须在其父节点上触发“inputcommited”。父级是请求表单(第一个代码片段),如您所见,它在输入中添加了“on-inputcommited”,告诉它触发自己的函数(又名 getinput)。也许我误解了整个事情,但我认为这就是它的工作原理._.
  • 为了简化它:我没有把自定义核心输入代码放在这里,但它有一个事件 on-change 。 on-change 触发 inputCommited(这是有效的),检查输入值是否有效(这也是有效的),然后告诉是否触发 inputcommited(全部为小写字母),应在 request-form(父级)中识别并触发 getinput。孩子和父母之间的通信出现问题,但 on-change 事件正在正确触发。

标签: polymer


【解决方案1】:

编辑:

从子元素中捕获自定义事件的另一种方法是在父元素的原型中进行: [1]、[2]

ready: function() {

        //select the custom-core-input(but first add this id attribute to it)
        var custom_core_input = this.$.id_custom_core_input;

         //wait for the event to fire
        this.addEventListener('inputCommited', function(e) {

        //Here comes inputCommited function code:

  });



<custom-core-input 
            columnId="12345678-1234-1234-123456789123"
            validation="^[0-9]*$" 
            inputRequired
            id="id_custom_core_input">
</custom-core-input>

【讨论】:

  • 问题是,每个自定义核心输入都是动态添加的,id 对我来说没有意义为每个人都设置一个 id。另外,我知道聚合物可以做一些我正在尝试的事情。我正在用我正在努力实现的工作(更简单)示例来更新我的问题。如果我没有做到这一点,我想我可以使用你的解决方案,但我更喜欢另一种方式。
  • 现在我明白你的意思了,我会将我的答案编辑为“捕获自定义事件的另一种方式”。
  • 你的方式很好,但我认为我尝试的方式更适合重复模板,因为你可以一次处理所有事件。但是,仍然无法使其以这种方式工作。如果您发现工作代码与我的代码不同,请告诉我。
猜你喜欢
  • 1970-01-01
  • 2017-06-29
  • 1970-01-01
  • 1970-01-01
  • 2018-05-19
  • 2018-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多