プロパティのプロパティ@
10780 ワード
LitElement それはWebコンポーネントの標準に基づいているので、軽量なWebアプリケーションを構築するための優れた代替手段です.
本稿では、実用化について説明する
ユーザーのリストを表示する小さなアプリケーションを構築しているとしましょう.あなたがそれらのいずれかを選択すると、他の詳細が表示される必要があります.この場合、アドレス情報である.
次に、LitElementを使用してWebコンポーネントを実装する前にデータモデルとデータセットを定義します.
モデルを準備するために、タイプスクリプトインターフェースと静的タイピングに頼りましょう.
テストを簡単にするには、前のモデルに一致するエンティティのデータセットを作成します.
LitElementプロパティを管理するためのさまざまな方法を提供します.ドキュメントが言うように
これは静的などちらかを使用して行うことができます
次のセクションでは、「プロパティ管理」をよりよく理解します.
最初のコンポーネントを含むクラスを作りましょう.この場合、ユーザーの一覧とその詳細を表示するコンテナコンポーネントを定義します.
The つのクラスプロパティを定義します. The The The The 前のコードは完璧です.しかし、それはまだデータを表示されません!我々は、ページのタイトルと空白のセクションだけを表示するユーザーのリストが表示されます.
このレンダリングの問題を解決するには、Webコンポーネントの更新サイクルをトリガーする必要があります.
しばらくすると更新サイクルを実行する必要があります:あなたがリストを変更するたびに
これらを識別したら、これらの属性をプロパティとして宣言する必要があります.
この 前の点から 言い換えれば、LitElementは、これらのプロパティの変更に対して「反応」し、テンプレートが自動的にレンダリング/更新されるようにします.
子コンポーネントを作成する前に、コンテナから使用する方法について考えてみましょう.Webコンポーネントでは、次の要素と属性が必要になるとしましょう.
前の考慮を考慮に入れて、新しいファイルを作成しましょう
The
The
The 受信する それは このメソッドをオーバーライドするたびにコールする必要があります The 真新しい
このコードを再生するには?StackBlitzエディタを開きます
質問があれば遠慮なく手を差し伸べる.フォローミーオンGitHub 私の仕事についてもっと見る.
このドットラボは、企業のデジタル変換の努力を実現支援に焦点を当てた現代のWebコンサルティングです.専門家の建築指導、訓練、またはコンサルティング、角度、Vue、Webコンポーネント、Graphql、ノード、バゼル、またはポリマー、訪問thisdotlabs.com .
このドットメディアは、すべての包括的で教育的なウェブを作成することに集中します.我々は最新のイベント、ポッドキャスト、および無料のコンテンツを介して近代的なWebの進歩と最新の状態に保つ.学ぶthisdot.co .
本稿では、実用化について説明する
@property
and @internalProperty
タイプスクリプト実装を使用したデコレータ問題
ユーザーのリストを表示する小さなアプリケーションを構築しているとしましょう.あなたがそれらのいずれかを選択すると、他の詳細が表示される必要があります.この場合、アドレス情報である.
次に、LitElementを使用してWebコンポーネントを実装する前にデータモデルとデータセットを定義します.
データモデリングとデータセット
データモデル
モデルを準備するために、タイプスクリプトインターフェースと静的タイピングに頼りましょう.
// 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
and address
簡単です:ユーザid
の位置と一致するaddress
配列.要素の使用
LitElementプロパティを管理するためのさまざまな方法を提供します.ドキュメントが言うように
LitElement manages your declared properties and their corresponding attributes.
これは静的などちらかを使用して行うことができます
properties
フィールドまたはデコレータを使用します.飾り付けの力を使って、タイプスクリプトの方法を取りましょう.次のセクションでは、「プロパティ管理」をよりよく理解します.
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デコレータを使用する
このレンダリングの問題を解決するには、Webコンポーネントの更新サイクルをトリガーする必要があります.
しばらくすると更新サイクルを実行する必要があります:あなたがリストを変更するたびに
users
! ただし、クラスから任意の変数や属性を更新するたびに行うことはできません.代わりに、どの属性が「操作」を実行するか、またはコンポーネントを更新しておくために、「キー」であることを言うべきです.LitElementプロパティをこれらのキー属性に呼び出します.これらを識別したら、これらの属性をプロパティとして宣言する必要があります.
// main-viewer.ts
@customElement("main-viewer")
class MainViewer extends LitElement {
// ...
@internalProperty() users: User[] = [];
@internalProperty() userId?: number;
constructor() {
super();
}
// ...
}
なぜ使用@internalProperty
この場合MainViewer
コンポーネントを参照する必要はありませんusers
or userId
コンポーネントの外部から.users
and userId
属性としてプライベートまたはプロテクト.@プロパティデコレータの使用
AddressViewerコンポーネントの作成
子コンポーネントを作成する前に、コンテナから使用する方法について考えてみましょう.Webコンポーネントでは、次の要素と属性が必要になるとしましょう.
<address-viewer .userId=${userId}></address-viewer>
それは新しいaddress-viewer
コンポーネントは「受信」する必要がありますuserId
それぞれのアドレスを取得できる値.The .userId=${userId}
表記は、データへの一方向のデータバインディングを適用しますAddressViewer
コンポーネントにはuserId
公共財産として.プロパティVSデコレーター
前の考慮を考慮に入れて、新しいファイルを作成しましょう
address-viewer.ts
: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]));
}
}
もう一度、前のソースコードを詳しく見てみましょう.- UserID属性は、@ propertyデコレータを使用しているコンポーネントのパブリックプロパティとして定義されます。
The
userAddress
プロパティは、コンポーネントのパブリックプロパティである必要はありません.代わりに、@internalProperty
それが変更されると、更新サイクルをトリガするデコレータ.-最初は未定義です
The
render
プロパティは、プロパティが変更されるたびにレンダリングされるHTMLコンテンツを返します.注意-この関数は、ユーザアドレスに必要なオブジェクトが含まれている場合にのみ、意味のあるテンプレートを返します。
The
update
関数はプロパティ値を反映し、render
関数.Map
変更されたプロパティを指定します.userId
プロパティが変更され、呼び出しを実行するloadAddress
. super.update()
テンプレートをレンダリングするにはloadAddress
関数は、userId
そして、アドレスオブジェクトを取得するユーティリティ関数を呼び出します.AddressViewer
コンポーネントは準備ができており、メインコンテナの子コンポーネントとして使用する必要があります.更新しましょうrender
以下のように機能します:// 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>
`;
}
// ...
}
一方、一方向データ結合に注意を払う.userId=${this.userId}
これは<address-viewer>
コンポーネントuserId
変更されます.これは魔法ですね.ライブデモ
このコードを再生するには?StackBlitzエディタを開きます
質問があれば遠慮なく手を差し伸べる.フォローミーオンGitHub 私の仕事についてもっと見る.
このドットラボは、企業のデジタル変換の努力を実現支援に焦点を当てた現代のWebコンサルティングです.専門家の建築指導、訓練、またはコンサルティング、角度、Vue、Webコンポーネント、Graphql、ノード、バゼル、またはポリマー、訪問thisdotlabs.com .
このドットメディアは、すべての包括的で教育的なウェブを作成することに集中します.我々は最新のイベント、ポッドキャスト、および無料のコンテンツを介して近代的なWebの進歩と最新の状態に保つ.学ぶthisdot.co .
Reference
この問題について(プロパティのプロパティ@), 我々は、より多くの情報をここで見つけました https://dev.to/thisdotmedia_staff/litelement-properties-property-vs-internalproperty-3ah1テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol