LitElement 속성: @property vs@internalProperty
10877 단어 litelementtypescript
본고에서 나는 TypeScript를 사용하여 실현된
@property
와 @internalProperty
장식기의 실제 사용을 설명할 것이다.문제.
사용자 목록을 표시할 작은 프로그램을 만들고 있다고 가정하십시오.그 중 하나를 선택하면 다른 세부 정보를 표시해야 합니다.이 경우 주소 정보입니다.
다음은 LitElement을 사용하여 웹 구성 요소를 실현하기 전에 데이터 모델과 데이터 집합을 정의합니다.
데이터 모델링과 데이터 집합
데이터 모델
TypeScript 인터페이스와 정적 유형을 사용하여 모델을 준비합니다.
// model.ts
export interface User {
id: number;
name: string;
}
export interface Address {
country: string;
state: string;
city: string;
street: string;
zipCode: number;
}
Address
인터페이스에 전체 주소를 나타내는 속성 세트가 표시됩니다.데이터의 출처
테스트를 더욱 쉽게 하기 위해서, 이전 모델과 일치하는 실체 데이터 집합을 만듭니다.
// data.ts
import { Address } from "./model";
import { User } from "./model";
export const users: User[] = [
{
id: 0,
name: "Donald Mayfield"
},
{
id: 1,
name: "Jill J. Fritz"
},
{
id: 2,
name: "Terry Buttram"
}
];
export const address: Address[] = [
{
street: "2180 BELLFLOWER",
country: "USA",
state: "AL",
city: "Madison",
zipCode: 35064
},
{
street: "845 ODOM ROAD, SUITE 200",
country: "USA",
state: "CA",
city: "Los Angeles",
zipCode: 90720
},
{
street: "9025 QUEENS BLVD",
country: "USA",
state: "NY",
city: "Queens",
zipCode: 11355
}
];
users
와address
사이의 관계는 매우 간단하다. 사용자id
와 address
수조의 위치가 일치한다.LitElement 속성 사용
LitElement은 다양한 방법으로 속성을 관리할 수 있습니다.파일에서 설명한 대로
LitElement manages your declared properties and their corresponding attributes.
이것은 정적
properties
필드나 장식기를 사용하여 완성할 수 있습니다.decorators의 강력한 기능을 사용하여 TypeScript를 사용하겠습니다.다음 부분을 통해 우리는 실천에서 부동산 관리를 더욱 잘 이해할 것이다.
MainViewer 컨테이너 만들기
첫 번째 구성 요소를 포함하는 클래스를 만듭니다.이 예에서, 우리는 용기 구성 요소를 정의할 것입니다. 이 구성 요소는 사용자 목록과 상세한 정보를 표시할 것입니다.
import {
LitElement,
html,
customElement,
css,
internalProperty
} from "lit-element";
import { users } from "./data";
import { User } from "./model";
@customElement("main-viewer")
class MainViewer extends LitElement {
static styles = css`
:host {
display: block;
}
`;
users: User[] = [];
userId?: number;
constructor() {
super();
}
render() {
return html`
<div>
<h1>User Address Viewer</h1>
<span>Select a User to see the Address:</span>
<ul>
${this.users.map(
user => html`
<li>
<a href="#" @click="${() => this.viewAddress(user.id)}"
>${user.name}</a
>
</li>
`
)}
</ul>
</div>
`;
}
async connectedCallback() {
super.connectedCallback();
this.users = await this.getUsers();
}
private getUsers() {
// in the real-world you'll get the data from a service, file, etc.
return new Promise<User[]>((resolve, reject) => resolve(users));
}
private viewAddress(id: number) {
this.userId = id;
}
}
지금까지 이 구성 요소에서 어떤 일이 일어났는지 설명합니다.static styles
속성은 태그의 템플릿 문자(css
를 사용하여 어셈블리의 스타일을 정의합니다.users
또한 userId
에는 선택한 사용자 식별자에 대한 참조가 포함됩니다(다른 사용자를 선택할 때마다 값이 변경됩니다).render
방법은 템플릿 텍스트 (html
를 통해 HTML 내용을 되돌려줍니다.구성 요소 속성이 바뀌면 이 함수를 호출합니다.connectedCallback
함수 호출getUsers
은 구성 요소를 문서의 DOM에 추가할 때 초기 데이터를 얻을 수 있도록 합니다.getUsers
함수는 비동기 호출(현실 장면에서)을 실행하여 데이터를 검색해야 한다.viewAddress
함수는 선택한 대상의 id
을 수신합니다.그런 다음 클래스 속성userId
이 업데이트됩니다.@internalProperty 장식기 사용하기
이 문제를 해결하기 위해서 웹 구성 요소의 업데이트 주기를 확보해야 합니다.
업데이트 주기를 언제 실행해야 할지 생각해 보세요: 목록이 바뀔 때마다!단, 이것은 클래스의 변수나 속성을 업데이트할 때마다 완성할 수 없습니다.대신 렌더링 작업을 수행하거나 어셈블리 업데이트를 유지하는 키 속성을 언급해야 합니다.이러한 주요 속성에 대해 LitElement 속성을 호출합니다.
이러한 속성이 확인되면 속성으로 선언해야 합니다.
// main-viewer.ts
@customElement("main-viewer")
class MainViewer extends LitElement {
// ...
@internalProperty() users: User[] = [];
@internalProperty() userId?: number;
constructor() {
super();
}
// ...
}
왜 이런 상황에서 사용합니까users
?@internalProperty
구성 요소에 대해 구성 요소 외부에서 인용MainViewer
하거나 users
할 필요가 없습니다.userId
와 users
속성을 사유 또는 보호받는 것으로 볼 수 있다.@property Decorator 사용
AddressViewer 구성 요소 만들기
서브어셈블리를 생성하기 전에 컨테이너에서 사용하는 방법을 생각해 보겠습니다.웹 구성 요소의 경우 다음과 같은 요소와 속성이 필요하다고 가정합니다.
<address-viewer .userId=${userId}></address-viewer>
이것은 새 userId
구성 요소가 해당하는 주소를 검색하려면 수신 address-viewer
값이 필요하다는 것을 의미한다.userId
기호는 단방향 데이터 귀속을 속성에 적용한다. 이것은 .userId=${userId}
구성 요소가 AddressViewer
를 공공 속성으로 하는 것을 의미한다.@속성 vs@internalProperty decorators
앞의 사항을 고려하여 새 파일을 만듭니다
userId
.import {
LitElement,
html,
property,
customElement,
css,
internalProperty
} from "lit-element";
import { address } from "./data";
import { Address } from "./model";
@customElement("address-viewer")
class AddressViewer extends LitElement {
static styles = css`
:host {
display: block;
}
table {
border-collapse: collapse;
width: 100%;
}
td,
th {
border: 1px solid gray;
text-align: left;
padding: 5px;
}
`;
@property({ type: Number }) userId: number;
@internalProperty() userAddress?: Address;
constructor() {
super();
}
render() {
if (this.userAddress === undefined) {
return html``;
}
return html`
<table>
<tr>
<th>Country</th>
<th>State</th>
<th>City</th>
<th>Street</th>
<th>Zip Code</th>
</tr>
<tr>
<td>${this.userAddress.country}</td>
<td>${this.userAddress.state}</td>
<td>${this.userAddress.city}</td>
<td>${this.userAddress.street}</td>
<td>${this.userAddress.zipCode}</td>
</tr>
</table>
`;
}
update(changedProperties: Map<string, unknown>) {
if (changedProperties.has("userId")) {
const oldValue = changedProperties.get("userId") as number;
console.log("userId updated, newVal", this.userId, "oldVal", oldValue);
this.loadAddress(this.userId);
}
super.update(changedProperties);
}
private async loadAddress(id: number) {
this.userAddress = await this.getAddress(id);
}
private getAddress(id: number) {
return new Promise<Address>((resolve, reject) => resolve(address[id]));
}
}
다시 한 번 앞의 소스 코드를 살펴보겠습니다.- 주소 뷰어ts 속성은 userId decorator를 사용하는 구성 요소의 공통 속성으로 정의됩니다.
@property
속성은 구성 요소의 공공 속성이 필요하지 않습니다.반대로, 이것은 userAddress
decorator를 사용하여 정의한 것으로, 변경되면 업데이트 주기를 촉발합니다.- 처음에는 @internalProperty
undefined
메서드는 속성을 변경할 때마다 표시할 HTML 내용을 반환합니다.- 참고: 함수는 필수 객체가 포함된 렌더링에만 의미 있는 템플릿을 반환합니다.
userAddress
함수는 속성 값을 반영하고 update
함수를 호출한다.render
을 받았습니다.Map
에 대한 호출을 실행합니다.userId
를 호출해서 템플릿을 보여야 한다.loadAddress
함수에서 super.update()
의 새 값을 가져오고 유틸리티 함수를 호출하여Address 대상을 검색합니다.loadAddress
구성 요소가 준비되어 있습니다. 메인 용기의 하위 구성 요소로 사용해야 합니다.다음과 같이 userId
함수를 업데이트합니다.// main-viewer.ts
// Let's import the <address-viewer> definition
import "./address-viewer";
@customElement("main-viewer")
class MainViewer extends LitElement {
//...
render() {
return html`
<div>
<h1>User Address Viewer</h1>
<span>Select a User to see the Address:</span>
<ul>
${this.users.map(
user => html`
<li>
<a href="#" @click="${() => this.viewAddress(user.id)}"
>${user.name}</a
>
</li>
`
)}
</ul>
<address-viewer .userId=${this.userId}></address-viewer>
</div>
`;
}
// ...
}
마찬가지로 단방향 데이터 귀속 AddressViewer
을 주의하십시오. render
구성 요소가 변경될 때 .userId=${this.userId}
구성 요소의 렌더링 동작을 터치합니다.이게 마법이야, 그렇지?현장 프레젠테이션
이 코드 한번 해볼래요?Stackblitz 편집기를 열려면 다음과 같이 하십시오.
문제가 있으면 언제든지 연락 주세요.계속해서 저GitHub를 주목해 주시고 제 일에 대한 더 많은 정보를 얻으세요.
현대 인터넷 컨설팅 회사로 기업의 디지털화 전환을 돕는 데 주력하고 있다.React, Angular, Vue, 웹 구성 요소,GraphQL,Node,Bazel 또는 Polymer에 대한 전문가 구조 지도, 교육 또는 문의는 방문thisdotlabs.com하십시오.
이런 인터넷 매체는 모든 사람을 위해 포용성과 교육적인 네트워크를 만드는 데 전념한다.이벤트, 팟캐스트, 무료 콘텐츠를 통해 현대 인터넷의 최신 진전을 알 수 있습니다.자세한 내용은 thisdot.co를 참조하십시오.
Reference
이 문제에 관하여(LitElement 속성: @property vs@internalProperty), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/thisdotmedia_staff/litelement-properties-property-vs-internalproperty-3ah1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)