聚合物1.0:如何从属性向聚合物函数传递参数?

39
有没有一种方法可以在Polymer函数中从元素属性内部的<template>传递参数?
<script src="http://www.polymer-project.org/1.0/samples/components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html" />
<dom-module id="example-element">
  <template>
    ...
    <paper-button id="foo" on-tap="bar">Click</paper-button>
    ...
  </template>
</dom-module>
<script>
  (function() {
    Polymer({
      is: 'example-element',
      properties: {...},
      bar: function(arg){
        // Do stuff using argument arg
      }
    });
  })();
</script>

背景研究

我浏览了文档,但未涉及此事。它没有说明是否可以或不可以。但是当我尝试时,失败了。但也许我没有做正确。所以我需要一些帮助。

我唯一找到的东西是事件监听器,但似乎无法传递我想要传递的参数,例如 id name

之前的尝试

我曾尝试(但失败)做过类似以下的事情:

<paper-button id="foo" on-tap="bar('foo')"> Click </paper-button>

但似乎没有任何方法有效。

事件监听器的想法行不通,因为它们限制了参数,我无法获取我需要的,比如说,id


一个同事说:总是像你的例子那样使用字面字符串吗?你可以这样做 on-tap="bar" data-bar="foo",然后在事件处理程序中使用 e.srcElement.getAttribute('data-bar')。你不能像你尝试的那样传递参数。 - Let Me Tink About It
8个回答

47
你可以使用HTML5数据属性代替。像这样尝试一下:
<paper-button id="foo" on-tap="bar" data-args="foo,some other value,2">Click</paper-button>
...
<script>
(function() {
  Polymer({
    is: 'example',
    properties: {...},
    bar: function(e){
      var args = e.target.getAttribute('data-args').split(',');
      // now args = ['foo', 'some other value', '2']
    }
  });
})();
</script>

5
实际上,我不得不使用Polymer.dom(e).path[2].getAttribute('data-args')。请参见此处:https://www.polymer-project.org/1.0/docs/devguide/events.html#retargeting 答案已被接受! - Let Me Tink About It
17
e.target.dataset.args 对我很有效,而且看起来更简洁。 - Andrew
@Andrew - 你说得对。那是更好和更干净的语法,而且考虑到我自己编写了HTML5,使用它是合法的。但实际上,如果使用dataset属性并按照我所做的方式进行操作,您将获得更好的向后兼容性。 - Amit
1
属性中的参数是什么,例如:data-args="{{some_prop}}",之前尝试的解决方案都不起作用。有什么想法吗?(@Amit @Mowzer) - Goce Ribeski
9
应该是:data-args$="{{some_prop}}",而不是 founded。请参考 https://www.polymer-project.org/1.0/docs/devguide/data-binding.html#attribute-binding。 - Goce Ribeski
我使用了 e.target.dataArgs 并且它起作用了(也许是更近期的版本?) - Mathter

46

经过大量搜索,我找到了我认为是最干净的解决方案。

如果paper-button在模板中,例如:

<template is="dom-repeat" items="{{allItems}}" as="item">
 <paper-button on-tap="itemTapped">[[item.text]]</paper-button>
</template>

然后可以通过传递给函数的事件对象中的"model"属性访问属性。

itemTapped: function(oEvent){
// oEvent.model.get is the getter for all properties of "item" in your bound array
console.log(oEvent.model.get('item.task'));
}

4
实际上,这是使用Polymer 1.7.0 API的正确答案,之前的答案现在已经过时了。 - Raffaeu
1
随着这个框架的快速发展,有时候 Stack Overflow 可能会误导 :)。 - Vaibhav Arora
1
item.task 中,task 代表什么?在上述模板中找不到它。 - sudheeshix
3
根据Polymer文档,这实际上是适用于 Polymer >= 1.x 的正确版本,因此应将其标记为正确。 - Raffaeu
1
这似乎与dom-repeat功能紧密相关:https://www.polymer-project.org/2.0/docs/devguide/templates#handling-events - GGirard
显示剩余2条评论

10

在上面的评论中提到了一个细微差别,现在更详细地说明。

注意,如果要读取数据绑定,则必须使用 $=

<paper-button on-tap="_handleTap" data-foo="foo" data-bar$="[[bar]]">Tap</paper-button>

...

_handleTap: function(e) {
  var foo = e.target.dataset.foo;
  var bar = e.target.dataset.bar;
}

dom-repeat 内,item(或其他您给予它的名称)可以通过 e.model.item 调用。

<template is="dom-repeat" items="[[items]]" as="someItem">
  <paper-button on-tap="_handleTap">Tap</paper-button>
</template>

...

_handleTap: function(e) {
  var item = e.model.someItem;
}

2
有没有办法从其<template>中的元素的属性向Polymer函数传递参数?不使用事件,而是使用计算绑定。计算绑定可以接受字面字符串。请查看下面的工作示例。在此示例中,可以根据传递的参数隐藏按钮。

<script src="http://www.polymer-project.org/1.0/samples/components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html" />
<dom-module id="example-element">
 <template>
  <button id="foo-one" on-tap="barEvent">Click foo-one</button>
  <button id="foo-two" hidden="{{barTest('value-two')}}">Click foo-two</button>
  <button id="foo-three" hidden="{{barTest('value-three')}}">Click foo-three</button>
 </template>
</dom-module>
<script>
 Polymer({
  is: "example-element",
  barEvent: function (event) {
   console.log(event.target.id);
  },
  barTest: function (arg) {
   if (arg === "value-two") {
    return true;
   } else {
    return false;
   }
  }
 });
</script>

<example-element></example-element>

注意:您可以通过event.target获取运行事件的元素的id或其他属性。如果您只是想要其他属性作为参数,这也可能是一个有效的解决方案。

1
嗯...这应该是正确的答案。简单明了。 - polarise

1

在尝试了这里提供的解决方案但没有一个有效后,我对@Amit和@Mowzer的解决方案进行了轻微修改,最终得以工作:

<dom-module id="dial-buttons">

    <template>
        <div on-click="handleClick" data-args="0, num-input">
            <p>0</p>
            <paper-ripple></paper-ripple>
        </div>
    </template>

    <script>
        Polymer({
            is: 'dial-buttons',
            properties: { ... },
            handleClick: function(e) {
                var args = Polymer.dom(e).path[1].getAttribute('data-args').split(',');
                alert(args[0] + args[1]);
            }
        });
    </script>

</dom-module>

0

刚刚我让它正常工作了:

<paper-button id="foo" on-tap="bar" data-args="baz,qux,quux">Click</paper-button>
...
<script>
(function() {
  Polymer({
    is: 'example',
    properties: {...},
    bar: function(e){
      var args = e.target.dataset.args.split(','); // ['baz', 'qux', 'quux']
    }
  });
})();
</script>

0
可能是检索参数最强大的方法如下:
<paper-button on-tap="_getArgs"
              data-args="foo,bar,qux">Click</paper-button>
...
_getArgs: function(e) {
  var args = Polymer.dom(e).rootTarget.getAttribute('data-args');
  ...
}

0
根据情况,通常清晰的做法是使用dom-repeat。如果您可以将数据格式化为对象数组,则只需使用e.model即可获取一切。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接