typescript 为什么垫树切换抛出错误时,用于创建故事文件?

xdnvmnnf  于 2023-06-30  发布在  TypeScript
关注(0)|答案(3)|浏览(117)

我已经在一个故事书模块中使用mat-tree创建了一个树组件,当我在一个组件中使用它时,它工作得很好。问题是当我用它来创造故事书中的故事时。在两种情况下使用相同的数据。
它抛出的第一个错误是:

'A valid data sorce must be provided'

当点击切换图标时,它给出以下错误:

Error: this._tree.treeControl.toggle is not a function     at MatTreeNodeToggle._toggle

是否与某种缺失的依赖性有关?
下面是树组件:

</mat-tree>
  <div class="box">
    <mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding>
      <button mat-icon-button matTreeNodeToggle [attr.aria-label]="'Toggle ' + node.title">
            <mat-icon>
                  {{ treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right' }}
            </mat-icon>
          </button>
          <span fxFlex class="nb-product-title" [innerHTML]="node.title || ''"></span>
        </mat-tree-node>
      </div>
    </mat-tree>

组件:

export class TreeComponent implements OnInit {
  @Input()
  treeData?: TreeData[];
private _transformer = (node: TreeData, level: number) => {
    return {
      expandable: !!node.children && node.children.length > 0,
      level: level,
      title: node.title,
      type: node.type || '',
      template: node.template || '',
      status: node.status || '',
      assignee: node.assignee || '',
      src: node.src || '',
    };
  };

  treeControl = new FlatTreeControl<TreeFlatNode>(
    node => node.level,
    node => node.expandable
  );

  treeFlattener = new MatTreeFlattener(
    this._transformer,
    node => node.level,
    node => node.expandable,
    node => node.children
  );

  dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);

  ngOnInit() {
    // @ts-ignore
    this.dataSource.data = this.treeData;
  }

  hasChild = (_: number, node: TreeFlatNode) => node.expandable;
}

我使用这个树组件的故事:

imports: [
        CommonModule,
        FlexModule,
        SharedModule,
        MatTreeModule,
        IconModule,
        MatChipsModule,
        ChipModule,
        MatIconModule,
        IconButtonModule,
        IconTextButtonModule,
        PaginationNavigationModule,
        ProfileModule,
        ButtonModule,
        HttpClientModule,
      ],
    }),
  ],
} as Meta;

const TREE_DATA: TreeData[] = [
  {
    title: 'some title text',
    type: 'radio',
    template: 'Live',
    status: 'Reduced',
    assignee: '',
    children: [
      {
        title: 'fj',
        type: 'home',
        template: 'Audio',
        status: 'Draft',
        assignee: 'string',
      },
      {
        title: 'fj',
        type: 'tv',
        template: 'Picture',
        status: 'Ready',
        assignee: 'string',
      },
    ],
  },
  {
    title: 'string',
    type: 'Web',
    template: 'Live',
    status: 'Draft',
    assignee: 'Tes',
  },
];

const Template: Story<TreeComponent> = (args: TreeComponent) => ({
  component: TreeComponent,
  props: args,
  template: '<app-tree' + ' [treeData]="treeData">' + '</app-tree>',
});

export const Tree = Template.bind({});
Tree.args = {
  treeData: TREE_DATA,
};
20jt8wwn

20jt8wwn1#

您需要将功能回复到故事书页面的组件中。

export class TreeComponent implements OnInit {
  @Input()
  treeData?: TreeData[];
_transformer = (node: TreeData, level: number) => {
    return {
      expandable: !!node.children && node.children.length > 0,
      level: level,
      title: node.title,
      type: node.type || '',
      template: node.template || '',
      status: node.status || '',
      assignee: node.assignee || '',
      src: node.src || '',
    };
  };

  treeControl = new FlatTreeControl<TreeFlatNode>(
    node => node.level,
    node => node.expandable
  );

  treeFlattener = new MatTreeFlattener(
    this._transformer,
    node => node.level,
    node => node.expandable,
    node => node.children
  );

  dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);

  ngOnInit() {
    // @ts-ignore
    this.dataSource.data = this.treeData;
  }

  hasChild = (_: number, node: TreeFlatNode) => node.expandable;
}

像这样进入故事书页面js

const TREE_DATA: TreeData[] = [
  {
    title: 'some title text',
    type: 'radio',
    template: 'Live',
    status: 'Reduced',
    assignee: '',
    children: [
      {
        title: 'fj',
        type: 'home',
        template: 'Audio',
        status: 'Draft',
        assignee: 'string',
      },
      {
        title: 'fj',
        type: 'tv',
        template: 'Picture',
        status: 'Ready',
        assignee: 'string',
      },
    ],
  },
  {
    title: 'string',
    type: 'Web',
    template: 'Live',
    status: 'Draft',
    assignee: 'Tes',
  },
];

 const _transformer = (node: TreeData, level: number) => {
        return {
          expandable: !!node.children && node.children.length > 0,
          level: level,
          title: node.title,
          type: node.type || '',
          template: node.template || '',
          status: node.status || '',
          assignee: node.assignee || '',
          src: node.src || '',
        };
      };
    
     const treeControl = new FlatTreeControl<TreeFlatNode>(
        node => node.level,
        node => node.expandable
      );
    
     const treeFlattener = new MatTreeFlattener(
        this._transformer,
        node => node.level,
        node => node.expandable,
        node => node.children
      );
const hasChild = (_: number, node: TreeFlatNode) => node.expandable;

const dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);

export const Tree = Template.bind({});
Tree.args = {
  treeData: TREE_DATA,
_transformer: _transformer,
treeControl: treeControl,
treeFlattener: treeFlattener,
hasChild: hasChild,
dataSource: dataSource
};
moiiocjp

moiiocjp2#

其实是故事书中的bug:https://github.com/storybookjs/storybook/issues/17004
目前的解决方法是:通过禁用main.js中的docs插件

qybjjes1

qybjjes13#

在我的例子中,我设法通过从控件中排除属性来使它工作,因此storybook不会将它们作为控件输入,也不会用控件面板中的字符串化版本覆盖属性。
使用与我在.stories.ts文件中添加的原始帖子相同的组件:

parameters: {
  controls: {
    exclude: ['dataSource', 'transformer', 'treeControl', 'treeFlattener', 'hasChild', 'hasNoContent'],
  }
}

相关问题