umbraco-state-management について
Umbraco のバックオフィス拡張向けに、リアクティブな状態管理を支援するスキルです。最新ドキュメントの確認から、Observable を使った状態とコンポーネント間通信のコード生成まで案内します。
主な機能
- 01Umbraco の状態コンテナのガイド
- 02Observable によるコンポーネント間更新
- 03文字列・数値・真偽値・配列・オブジェクトの状態
- 04選択値に基づく派生 Observable
- 05状態を非公開にし Observable を公開
活用シーン
- 01コンテキストと UI 要素間で状態を共有
- 02値の変更に応じたリアクティブ UI の更新
- 03疎結合なコンポーネント間の通信
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ umbraco/ umbraco-cms-backoffice-skills --skill umbraco-state-managementインストール後、Claude Code で/umbraco-state-managementを入力して読み込まれたか確認します。
詳細
Umbraco の状態管理
これは何ですか?
Umbraco の状態(State)は、Observable パターンを使用してコンポーネントインスタンス間の通信を可能にする、リアクティブな値のコンテナです。Umbraco の状態とは、値のコンテナであり、そこから Observable を作成できます。これにより、複数のオブザーバーが購読し、状態が変化したときに自動的に更新を受け取ることができます。このパターンは、密結合させることなくコンテキストと要素の間でデータを共有する場合に特に役立ちます。
ドキュメント
実装する前に、常に最新のドキュメントを取得してください:
- メインドキュメント: https://docs.umbraco.com/umbraco-cms/extend-your-project/backoffice-extensions/foundation/states
- Foundation: https://docs.umbraco.com/umbraco-cms/extend-your-project/backoffice-extensions/foundation
- Context API: https://docs.umbraco.com/umbraco-cms/extend-your-project/backoffice-extensions/foundation/context-api
ワークフロー
- ドキュメントを取得 - 上記の URL に対して WebFetch を使用します
- 質問する - どのような種類の状態ですか? 誰がオブザーブしますか? どこで Observable を提供しますか?
- コードを生成 - 最新のドキュメントに基づいて、Observable を使用した状態を実装します
- 説明する - 何が作成されたか、そしてオブザーブがどのように機能するかを示します
最小限の例
基本的な状態の使用
import { UmbStringState } from '@umbraco-cms/backoffice/observable-api';
// Create a state with initial value
const myState = new UmbStringState('initial value');
// Create an observable from the state
const myObservable = myState.asObservable();
// Observe the state (fires immediately and on changes)
this.observe(myObservable, (value) => {
console.log('Current value:', value);
});
// Update the state (all observers notified)
myState.setValue('updated value');
コンテキストパターンでの状態
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
import { UmbNumberState } from '@umbraco-cms/backoffice/observable-api';
export class MyContext extends UmbContextBase<MyContext> {
// Private state
#counter = new UmbNumberState(0);
// Public observable (readonly)
readonly counter = this.#counter.asObservable();
increment() {
this.#counter.setValue(this.#counter.getValue() + 1);
}
decrement() {
this.#counter.setValue(this.#counter.getValue() - 1);
}
}
コンテキストの状態をオブザーブする要素
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { MY_CONTEXT } from './my-context.js';
export class MyElement extends UmbLitElement {
@state()
private _count = 0;
constructor() {
super();
this.consumeContext(MY_CONTEXT, (context) => {
// Observe the counter state from context
this.observe(
context.counter,
(count) => {
this._count = count;
},
'_countObserver'
);
});
}
render() {
return html`
<div>Count: ${this._count}</div>
`;
}
}
さまざまな状態の種類
import {
UmbStringState,
UmbNumberState,
UmbBooleanState,
UmbArrayState,
UmbObjectState
} from '@umbraco-cms/backoffice/observable-api';
// String state
const name = new UmbStringState('John');
// Number state
const age = new UmbNumberState(25);
// Boolean state
const isActive = new UmbBooleanState(true);
// Array state
const items = new UmbArrayState(['item1', 'item2']);
// Object state
const user = new UmbObjectState({ name: 'John', age: 25 });
Observable パーツ(派生状態)
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
const itemsState = new UmbArrayState(['apple', 'banana', 'cherry']);
// Observe just the first item
const firstItem = itemsState.asObservablePart(data => data?.[0]);
// Observe just the count
const itemCount = itemsState.asObservablePart(data => data.length);
// Use in element
this.observe(firstItem, (first) => {
console.log('First item:', first);
});
this.observe(itemCount, (count) => {
console.log('Total items:', count);
});
配列状態の操作
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
const listState = new UmbArrayState<string>([]);
// Add item
listState.setValue([...listState.getValue(), 'new item']);
// Remove item
listState.setValue(
listState.getValue().filter(item => item !== 'old item')
);
// Clear all
listState.setValue([]);
// Get current value
const current = listState.getValue();
完全なコンテキストの例
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
import { UmbStringState, UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
export class TodoContext extends UmbContextBase<TodoContext> {
#title = new UmbStringState('My Todo List');
#todos = new UmbArrayState<string>([]);
readonly title = this.#title.asObservable();
readonly todos = this.#todos.asObservable();
readonly todoCount = this.#todos.asObservablePart(data => data.length);
setTitle(value: string) {
this.#title.setValue(value);
}
addTodo(todo: string) {
this.#todos.setValue([...this.#todos.getValue(), todo]);
}
removeTodo(todo: string) {
this.#todos.setValue(
this.#todos.getValue().filter(t => t !== todo)
);
}
}
主要な概念
状態(State): 値のコンテナ(プライベート、ミュータブル)
Observable: 状態から作成される購読フック(パブリック、読み取り専用)
オブザーバー: observe() を介して状態の変化に反応する関数
状態の種類:
UmbStringState- テキスト値UmbNumberState- 数値UmbBooleanState- 真偽値フラグUmbArrayState- コレクションUmbObjectState- 複雑なオブジェクトUmbClassState- クラスインスタンス
Observable パーツ: マップされた値が変化したときにのみ更新される派生 Observable
ベストプラクティス: 状態はプライベートに保ち、Observable をパブリックに公開する
ユースケース:
- コンテキストと要素の間でデータを共有する
- リアクティブな UI 更新
- コンポーネント間の通信
- 派生値/計算値
以上です! 常に最新のドキュメントを取得し、例は最小限に保ち、完全に動作するコードを生成してください。
コメント
Markdown 対応