簡體   English   中英

Fabric UI DetailsList 控件 - 動態加載組項目

[英]Fabric UI DetailsList control - Dynamically load group items

我在自定義 SPFx webpart 中使用分組的 DetailsList Fabric UI 組件來顯示列表數據

我需要在組展開后通過 API 調用從服務器動態加載組的項目,但在 DetailsList 組件中找不到任何可用的組展開回調,其中包含可用的公開組道具(組名等)作為方法用於構建請求字符串的參數。 它應該是這樣的:

https://contoso.sharepoint.com/site/_api/web/Lists/getbytitle('ListTitle')/RenderListDataAsStream?@listUrl=&View=&IsGroupRender=TRUE&DrillDown=1&GroupString=%3B%23Exel%20Format%20Files%3B%23%3B%23&

基本上,我想實現 Sharepoint 2019 中存在的標准現代文檔庫 webpart 的行為。只需要對更新項目數組的組展開回調。 使用 DetailsList 組件還有其他方法可以實現這一點嗎?

組件的代碼示例(來自文檔):

import * as React from 'react';
import {
  BaseComponent,
  DefaultButton,
  DetailsHeader,
  DetailsList,
  IColumn,
  IDetailsHeaderProps,
  IDetailsList,
  IGroup,
  IRenderFunction,
  IToggleStyles,
  mergeStyles,
  Toggle
} from 'office-ui-fabric-react';

const margin = '0 20px 20px 0';
const controlWrapperClass = mergeStyles({
  display: 'flex',
  flexWrap: 'wrap'
});
const toggleStyles: Partial<IToggleStyles> = {
  root: { margin: margin },
  label: { marginLeft: 10 }
};

export interface IDetailsListGroupedExampleItem {
  key: string;
  name: string;
  color: string;
}

export interface IDetailsListGroupedExampleState {
  items: IDetailsListGroupedExampleItem[];
  groups: IGroup[];
  showItemIndexInView: boolean;
  isCompactMode: boolean;
}
const _blueGroupIndex = 2;

export class DetailsListGroupedExample extends BaseComponent<{}, IDetailsListGroupedExampleState> {
  private _root = React.createRef<IDetailsList>();
  private _columns: IColumn[];

  constructor(props: {}) {
    super(props);

    this.state = {
      items: [
        { key: 'a', name: 'a', color: 'red' },
        { key: 'b', name: 'b', color: 'red' },
        { key: 'c', name: 'c', color: 'blue' },
        { key: 'd', name: 'd', color: 'blue' },
        { key: 'e', name: 'e', color: 'blue' }
      ],
      // This is based on the definition of items
      groups: [
        { key: 'groupred0', name: 'Color: "red"', startIndex: 0, count: 2 },
        { key: 'groupgreen2', name: 'Color: "green"', startIndex: 2, count: 0 },
        { key: 'groupblue2', name: 'Color: "blue"', startIndex: 2, count: 3 }
      ],
      showItemIndexInView: false,
      isCompactMode: false
    };

    this._columns = [
      { key: 'name', name: 'Name', fieldName: 'name', minWidth: 100, maxWidth: 200, isResizable: true },
      { key: 'color', name: 'Color', fieldName: 'color', minWidth: 100, maxWidth: 200 }
    ];
  }

  public componentWillUnmount() {
    if (this.state.showItemIndexInView) {
      const itemIndexInView = this._root.current!.getStartItemIndexInView();
      alert('first item index that was in view: ' + itemIndexInView);
    }
  }

  public render() {
    const { items, groups, isCompactMode } = this.state;

    return (
      <div>
        <div className={controlWrapperClass}>
          <DefaultButton onClick={this._addItem} text="Add an item" styles={{ root: { margin: margin } }} />
          <Toggle label="Compact mode" inlineLabel checked={isCompactMode} onChange={this._onChangeCompactMode} styles={toggleStyles} />
          <Toggle
            label="Show index of first item in view when unmounting"
            inlineLabel
            checked={this.state.showItemIndexInView}
            onChange={this._onShowItemIndexInViewChanged}
            styles={toggleStyles}
          />
        </div>
        <DetailsList
          componentRef={this._root}
          items={items}
          groups={groups}
          columns={this._columns}
          ariaLabelForSelectAllCheckbox="Toggle selection for all items"
          ariaLabelForSelectionColumn="Toggle selection"
          onRenderDetailsHeader={this._onRenderDetailsHeader}
          groupProps={{
            showEmptyGroups: true
          }}
          onRenderItemColumn={this._onRenderColumn}
          compact={isCompactMode}
        />
      </div>
    );
  }

  private _addItem = (): void => {
    const items = this.state.items;
    const groups = [...this.state.groups];
    groups[_blueGroupIndex].count++;

    this.setState(
      {
        items: items.concat([
          {
            key: 'item-' + items.length,
            name: 'New item ' + items.length,
            color: 'blue'
          }
        ]),
        groups
      },
      () => {
        if (this._root.current) {
          this._root.current.focusIndex(items.length, true);
        }
      }
    );
  };

  private _onRenderDetailsHeader(props: IDetailsHeaderProps, _defaultRender?: IRenderFunction<IDetailsHeaderProps>) {
    return <DetailsHeader {...props} ariaLabelForToggleAllGroupsButton={'Expand collapse groups'} />;
  }

  private _onRenderColumn(item: IDetailsListGroupedExampleItem, index: number, column: IColumn) {
    const value = item && column && column.fieldName ? item[column.fieldName as keyof IDetailsListGroupedExampleItem] || '' : '';

    return <div data-is-focusable={true}>{value}</div>;
  }

  private _onShowItemIndexInViewChanged = (event: React.MouseEvent<HTMLInputElement>, checked: boolean): void => {
    this.setState({ showItemIndexInView: checked });
  };

  private _onChangeCompactMode = (ev: React.MouseEvent<HTMLElement>, checked: boolean): void => {
    this.setState({ isCompactMode: checked });
  };
}

我今天也在尋找這個,在檢查源代碼后我想通了。 使用groupProps.headerProps設置組折疊/展開的回調

<DetailsList
    ...
    groupProps={{           
        headerProps: {
            onToggleCollapse: this._onGroupToggleCollapse
        }
    }}
/>

因此,此操作的基本邏輯是(使用 onToggleCollapse 回調):

private _onToggleCollapse(props: IGroupDividerProps): () => void {
  ...
  if (props.group.data.isLoaded === false && props.group.isCollapsed === false && props.group.level > 0) {
   ...
   let data: any = this._getGroupItems(props.group, isLoadAll, {}).then((resp: any) => {
    resp.json().then((responseJSON: any) => {
     ...
     updatedItems = this.state.items.map((el: any, i: number) => {
      ...
     });
     ...
     this.setState({
      items: [...updatedItems],
      groups: [...this.state.groups]
     });
    });
   });
   ...
  }
  ...
  return () => {
   props.onToggleCollapse!(props!.group!);
  };
 }

我們需要檢查擴展以防止更新組崩潰。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM