跳转到内容

hideWhen / disableWhen / valueChange — 动态控制 API 参考

本文介绍这几个 Action 的参数说明和使用方式。

参数 必填 说明
listen 监听回调,返回 boolean 形式的 Observable:true → 隐藏,false → 显示
disabled 隐藏时是否同时禁用字段

listen 接收两个参数:

  • fn:订阅其他字段值的函数,调用时传入
    • list:要监听的字段路径数组
    • skipInitValue:为 true 时组件初始化不触发回调
  • field:当前字段

fn(...) 返回的对象里能拿到 field(当前字段)、list(各监听字段的当前值)、listenFields(各监听字段的字段实例)。

fn() 返回的 Observable 中包含 listenFields 数组,对应 list 中每个路径的字段实例:

import { hideWhen } from '@piying/view-angular-core';
import { map } from 'rxjs';

const schema = v.object({
  showExtra: v.boolean(),
  extraField: v.pipe(
    v.string(),
    hideWhen({
      listen: (fn) =>
        fn({ list: [['..', 'showExtra']] }).pipe(
          map((item) => !item.list[0]), // showExtra = false → 隐藏
        ),
    }),
  ),
});
const schema = v.object({
  enable: v.boolean(),
  name: v.pipe(
    v.string(),
    hideWhen({
      disabled: true, // 隐藏时同时禁用
      listen: (fn) => fn({ list: [['..', 'enable']] }).pipe(map((item) => !item.list[0])),
    }),
  ),
});

enable = false 时,name 同时被隐藏和禁用

参数与 hideWhen 一致,只需要 listen:回调返回 true → 禁用,false → 启用。

特性 disableWhen hideWhen({ disabled: true })
功能 仅控制 disabled 同时控制 hidden + disabled
适用场景 字段可见但不可编辑 字段不可见且不可编辑
import { disableWhen } from '@piying/view-angular-core';
import { map } from 'rxjs';

const schema = v.object({
  isLocked: v.boolean(),
  name: v.pipe(
    v.string(),
    disableWhen({
      listen: (fn) =>
        fn({ list: [['..', 'isLocked']] }).pipe(
          map((item) => item.list[0]), // isLocked = true → 禁用
        ),
    }),
  ),
});

valueChange — 值变化监听(无副作用)

Section titled “valueChange — 值变化监听(无副作用)”

输入一个监听回调,参数与 hideWhenlisten 相同;在回调里自行 subscribe 处理,不需要返回结果。

valueChange 只监听值变化,不产生任何副作用(不改 hidden/disabled),适用于自定义联动逻辑。

import { valueChange } from '@piying/view-angular-core';

const schema = v.object({
  source: v.string(),
  target: v.pipe(
    v.string(),
    valueChange((fn) =>
      fn({ list: [['..', 'source']] }).subscribe((value) => {
        // 自定义逻辑:监听 source 变化,执行自己的操作
        console.log('source changed to:', value.list[0]);
      }),
    ),
  ),
});
hideWhen({
  listen: (fn) =>
    fn({
      list: [['..', 'field']],
      skipInitValue: true, // 组件初始化时不触发回调
    }).pipe(map((item) => !item.list[0])),
});

所有三个 Action 的回调都在 allFieldsResolved Hook 中执行:

mergeHooksFn(
  {
    allFieldsResolved: (field) => {
      options
        .listen((options) => valueChangeFn(field, options), field)
        .subscribe((result) => {
          /* 更新 hidden/disabled */
        });
    },
  },
  { position: 'bottom' },
  field,
);

这意味着这三个 Action 必须在所有字段解析完成后才能正确获取监听字段的引用。

outputChange 监听组件的自定义输出事件(如 @Output() / emit 事件),支持多字段监听。

输入一个回调,回调接收 fn;调用 fn(list) 订阅输出事件,list 每一项包含:

  • list:目标字段路径,undefined 表示当前字段自身
  • output:要监听的输出事件名

注意:事件处理器实际上是合并到当前字段自身的 outputs 上,list 中指定的字段只影响 listenFields 的映射关系。

import { outputChange } from '@piying/view-angular-core';

const schema = v.object({
  childField: v.pipe(
    v.string(),
    actions.outputs.set({ myEvent: (value) => console.log('event:', value) }),
    outputChange((fn) =>
      fn([
        { list: undefined, output: 'myEvent' },
        { list: ['..', 'otherField'], output: 'otherEvent' },
      ]).subscribe((result) => {
        console.log('output change:', result);
      }),
    ),
  ),
});