Reputation: 2149
How to use Lit-element with Object-type property? I think defining myelement works:
static get properties() {
return {
whales:Object
}
}
constructor() {
super();
this.whales={"nb":0};
}
html, this works also:
<my-element id="mytest" whales='{"nb":2}'></my-element>
But I can't get setAttribute to work:
myElement.setAttribute("whales", {"nb":4});
EDIT: Thank you mishu, your answer helped me to solve my problem. Here is full working example, if someone wants to know. However there is still one thing I couldn't get working: I don't know how to give a property initial value declaratively, if the value is an object (object is handled as a string).
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Lit-html test</title>
</head>
<body>
<script type="module" src="./components/my-e.js"></script>
<button id="reset" onclick="reset()">reset</button>
<p>1 works: <my-e id="mytest"></my-e></p>
<p>2 doesn't work: <my-e id="mytest2" person='{"name":"Joe", "age":32}'></my-e></p>
<script src="main.js"></script>
</body>
</html>
main.js:
function updatePerson(e) {
var myE = e.target;
myE.person = e.detail;
myE._requestRender();
}
function reset() {
var p = { "name": "Jack", "age": 20 };
var myE = document.getElementById('mytest');
myE.person = p;
myE._requestRender();
myE = document.getElementById('mytest2');
myE.person = p;
myE._requestRender();
}
document.getElementById('mytest').addEventListener('person', updatePerson);
document.getElementById('mytest2').addEventListener('person', updatePerson);
my-e.js:
import { LitElement, html } from './lit-element.js';
class MyE extends LitElement {
static get properties() {
return {
person: Object
}
}
constructor() {
super();
this.person = { "name": "Paul", "age": 40 };
this.addEventListener('click', async (e) => {
await this.renderComplete;
var p = {};
p.name = this.person.name + ", a";
p.age = this.person.age + 1;
this.dispatchEvent(new CustomEvent('person', { detail: p }))
});
}
_render({ person }) {
return html`
<p> Name: ${person.name}</p>
<p>Age: ${person.age}</p>
`;
}
}
customElements.define('my-e', MyE);
Upvotes: 3
Views: 9083
Reputation: 377
This example is tested in Lit 2.3.1. It should also work with lit-element.
Note: While passing object type attribute through html outer quotes must be single quotes and inner quotes must be double quotes.( like this: article='{"title": "Hello"}' ).
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lit 2.3.1</title>
</head>
<body>
<my-page article='{"title": "Hello", "text": "World", "lines": 120}'></my-page>
</body>
</html>
my-page.js
import {LitElement, html} from 'lit';
class MyPage extends LitElement {
static properties = {
article: {
type: Object,
attribute: 'article'
}
};
render() {
return html`
<div>
<p>${this.article.title}</p>
<p>${this.article.text}</p>
<p>${this.article.lines}</p>
</div>`;
}
}
customElements.define('my-page', MyPage);
Upvotes: 0
Reputation: 1901
<my-e id="mytest2" person='{"name":"Joe", "age":32}'></my-e>
Should have been
<my-e id="mytest2" person='${{"name":"Joe", "age":32}}'></my-e>
If you are using lit-extended. But this notation is going to be removed and is currently deprecated.
Hence the better option would be to write it as:
<my-e id="mytest2" .person={"name":"Joe", "age":32}></my-e>
You can find the details at this documentation
Upvotes: 1
Reputation: 5397
There you are trying to update a property, not really to set an attribute, and you don't have reflectToAttribute
on the property. But you can try to use simply:
myElement.whales = {nb: 4};
UPDATE: I see that you changed the "scope" of the question.. so, you should be able to pass an object declaratively as long as the JSON is correct. You can see it in this demo.
Upvotes: 3