在元素定义上绑定属性字典
Bind dictionary of attributes on element definition
我在定义元素时试图绑定像 {'id': 'myid', 'class': 'my-1 pr-md-2', ...}
这样的属性字典。我不想在 DOM 被 Javascript 加载后设置该属性。
我正在努力寻找正确的执行方式。我无法通过手动声明属性名称和值来一一绑定它们,因为它们是用户给定的参数。我考虑过将它们附加到 attributes
属性,但我不知道这样做是否可取。
这是我的数据结构:
<template is="dom-repeat" items="{{links}}" as="link">
<a class="nav-item nav-link mr-md-2" on-tap="changePage">{{link.title}}</a>
</template>
并且属性保存在每个link.attributes
属性中。我的解决方案是这样的:
HTML
<template is="dom-repeat" items="{{links}}" as="link">
<a attributes={{appendAttributes(link)}} class="nav-item nav-link mr-md-2" on-tap="changePage">{{link.title}}</a>
</template>
JS
appendAttributes: function(link){
//Get current attributes of the element and append the ones in link.attributes
}
这是正确的处理方式吗?
据我所知,Polymer 的模板系统无法做到这一点:there's no way 访问应用计算绑定的元素。
这个
<a attributes={{appendAttributes(link)}}></a>
无法工作,因为 attributes
属性 是 read-only。
I can not bind them one by one declaring the attribute name and value manually as they are user given parameters
实际上如果你事先知道什么 attributes/properties必须设置你仍然可以动态设置它们:
<a id=[[userGivenId]]
class$=[[userGivenClass]]
...
></a>
无论如何,open-wc
制定了一个名为 spread 的 lit-html
指令,它可以满足您的需求。这需要使用 LitElement 重写您的组件,如下所示:
import { LitElement, html, property, customElement } from 'lit-element';
import { repeat } from 'lit-html/directives/repeat';
import { spread } from '@open-wc/lit-helpers';
@customElement('my-element')
export class MyElement extends LitElement {
@property() userGivenId;
@property() links;
// ...
render() {
return html`
${repeat(this.links, link => html`
<a ...=${spread({
id: this.userGivenId,
'?my-boolean-attribute': true
'.myProperty': { foo: 'bar' },
'@my-event': () => console.log('my-event fired'),
})}
class="nav-item nav-link mr-md-2"
@click=${e => this.changePage(e)}
>${link.title}</a>
`)}
`;
}
}
由于某些限制,PolymerElement
s 和 LitElement
s 可以共存于同一个项目中,因此转换单个组件不会造成任何麻烦。
我在定义元素时试图绑定像 {'id': 'myid', 'class': 'my-1 pr-md-2', ...}
这样的属性字典。我不想在 DOM 被 Javascript 加载后设置该属性。
我正在努力寻找正确的执行方式。我无法通过手动声明属性名称和值来一一绑定它们,因为它们是用户给定的参数。我考虑过将它们附加到 attributes
属性,但我不知道这样做是否可取。
这是我的数据结构:
<template is="dom-repeat" items="{{links}}" as="link">
<a class="nav-item nav-link mr-md-2" on-tap="changePage">{{link.title}}</a>
</template>
并且属性保存在每个link.attributes
属性中。我的解决方案是这样的:
HTML
<template is="dom-repeat" items="{{links}}" as="link">
<a attributes={{appendAttributes(link)}} class="nav-item nav-link mr-md-2" on-tap="changePage">{{link.title}}</a>
</template>
JS
appendAttributes: function(link){
//Get current attributes of the element and append the ones in link.attributes
}
这是正确的处理方式吗?
据我所知,Polymer 的模板系统无法做到这一点:there's no way 访问应用计算绑定的元素。
这个
<a attributes={{appendAttributes(link)}}></a>
无法工作,因为 attributes
属性 是 read-only。
I can not bind them one by one declaring the attribute name and value manually as they are user given parameters
实际上如果你事先知道什么 attributes/properties必须设置你仍然可以动态设置它们:
<a id=[[userGivenId]]
class$=[[userGivenClass]]
...
></a>
无论如何,open-wc
制定了一个名为 spread 的 lit-html
指令,它可以满足您的需求。这需要使用 LitElement 重写您的组件,如下所示:
import { LitElement, html, property, customElement } from 'lit-element';
import { repeat } from 'lit-html/directives/repeat';
import { spread } from '@open-wc/lit-helpers';
@customElement('my-element')
export class MyElement extends LitElement {
@property() userGivenId;
@property() links;
// ...
render() {
return html`
${repeat(this.links, link => html`
<a ...=${spread({
id: this.userGivenId,
'?my-boolean-attribute': true
'.myProperty': { foo: 'bar' },
'@my-event': () => console.log('my-event fired'),
})}
class="nav-item nav-link mr-md-2"
@click=${e => this.changePage(e)}
>${link.title}</a>
`)}
`;
}
}
由于某些限制,PolymerElement
s 和 LitElement
s 可以共存于同一个项目中,因此转换单个组件不会造成任何麻烦。