可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Is there a way to pass an argument to a Polymer function from an element attribute inside its <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>
Background Research
I have combed through the documentation which appears silent on the matter. It doesn't say whether you can or can not. But when I try it, it fails. But maybe I'm not doing it correctly. So I need some assistance.
The only thing I have come across is event listeners which doesn't seem to be able to take the arguments I want to pass. Say, an id
or a name
.
Previous Attempts
I have tried (unsuccessfully) doing things like:
<paper-button id="foo" on-tap="bar('foo')"> Click </paper-button>
but nothing seems to work.
The event listeners idea doesn't work because they limit the arguments and I can't get the, say, id
I need.
回答1:
You could utilize HTML5 data attributes instead. Try like this:
<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>
回答2:
After searching a lot, I found what I think is the cleanest possible solution.
If the paper-button is inside a template, e.g.
<template is="dom-repeat" items="{{allItems}}" as="item">
<paper-button on-tap="itemTapped">[[item.text]]</paper-button>
</template>
Then the properties can be accessed via "model" property in event object passed to function.
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'));
}
回答3:
Shining more light on a subtle difference mentioned in the comments above.
Notice $=
must be used if reading a data binding.
<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;
}
Inside dom-repeat
, the item
(or whichever name you give it) is available at 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;
}
回答4:
Is there a way to pass an argument to a Polymer function from an attribute of an element inside its <template>
.
Instead of using an event use a computed binding. Computed bindings can accept literal strings.
Checkout the working example below. In this example a button can be hidden based on the parameter that is passed.
<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>
Note: You can get the id
or other attributes of an element that an event is run on through event.target
. If you are only looking for other attributes as parameters this might also be a valid solution.
回答5:
After trying the solutions suggested here which none of them worked, I did a slight modification of @Amit and @Mowzer solutions I got it working like this:
<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>
回答6:
Just now I got this to work:
<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>
回答7:
Possibly the most robust way to retrieve the argument is as follows:
<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');
...
}
回答8:
Depending on the situation, the clean way to do this is usually using dom-repeat. If you can format your data as an array of objects, you can just use e.model to get everything.