mcpField
U
umbraco-state-management

umbraco-state-management

github.com/umbraco开发27376 次安装6 周前更新
代码仓库

关于 umbraco-state-management

面向 Umbraco 后台扩展开发的状态管理技能,指导开发者查阅最新文档,并用 Observable 构建响应式状态与跨组件通信。

主要功能

  1. 01Umbraco 状态容器使用指导
  2. 02基于 Observable 的跨组件更新
  3. 03字符串、数字、布尔值、数组和对象状态
  4. 04针对选定值创建派生 Observable
  5. 05状态私有化并公开 Observable

适用场景

  1. 01在上下文与界面元素间共享状态
  2. 02值变化时更新响应式界面
  3. 03在低耦合组件间通信

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/umbraco/umbraco-cms-backoffice-skills --skill umbraco-state-management

安装后在 Claude Code 中输入/umbraco-state-management确认已加载。

详细介绍

Umbraco 状态管理

这是什么?

Umbraco 中的状态是用于存储响应式值的容器,可通过 Observable 模式在多个组件实例之间进行通信。Umbraco 状态是一个值容器,你可以基于它创建 Observable,让多个观察者订阅,并在状态发生变化时自动接收更新。此模式尤其适合在不同上下文和元素之间共享数据,同时避免紧密耦合。

文档

实现前务必获取最新文档:

工作流

  1. 获取文档 - 使用 WebFetch 访问上述 URL
  2. 提出问题 - 状态的类型是什么?谁来观察?在哪里提供 observable?
  3. 生成代码 - 根据最新文档,使用 observables 实现状态
  4. 说明 - 展示创建的内容以及观察机制的工作方式

最简示例

基本状态用法
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)
    );
  }
}

核心概念

状态:值的容器(私有、可变)

Observable:基于状态创建的订阅钩子(公开、只读)

观察者:通过 observe() 响应状态变化的函数

状态类型:

  • UmbStringState - 文本值
  • UmbNumberState - 数值
  • UmbBooleanState - 布尔标志
  • UmbArrayState - 集合
  • UmbObjectState - 复杂对象
  • UmbClassState - 类实例

Observable 部分:仅在映射后的值发生变化时才更新的派生 observables

最佳实践:将状态设为私有,对外公开 observables

使用场景:

  • 在上下文和元素之间共享数据
  • 响应式 UI 更新
  • 跨组件通信
  • 派生值/计算值

就是这样!务必获取最新文档,保持示例简洁,并生成完整可运行的代码。

评论

支持 Markdown