SPFX - 长时间间隔后刷新 Web 部件

Posted

技术标签:

【中文标题】SPFX - 长时间间隔后刷新 Web 部件【英文标题】:SPFX - Refreshing Web Part after long interval 【发布时间】:2019-02-18 17:25:34 【问题描述】:

我正在编写一个 Web 部件以从 SharePoint Online 查询数据,返回的数据使用 DetailsList 组件显示,我遇到的问题是查询需要很长时间才能返回结果,Web 部件没有'不刷新并停留在“空白”页面上:

对于需要 1-2 秒的快速查询,Web 部件会更新并正常显示结果:

我还想通过使用 displayLoadingIndicator() 向我的用户提供反馈,以显示 Web 部件正忙,但我无法使其正常工作。

这是我的代码(为简单起见):

- NavigatorWebPart.ts

export default class NavigatorWebPart extends BaseClientSideWebPart<INavigatorWebPartProps> 

  protected onInit(): Promise<void> 
    this.context.statusRenderer.displayLoadingIndicator(this.domElement, "Querying items...");
    return super.onInit();
  

  public render(): void 
    const element: React.ReactElement<INavigatorProps> = React.createElement(Navigator, );
    ReactDom.render(element, this.domElement);
  

- Navigator.tsx

let listItems : any[] = [];
const listColumns : IColumn[] = [...  // shortened for brevity

export default class Navigator extends React.Component<INavigatorProps, IListMembers> 

  constructor(props) 
    super(props);

    this.queryLists();

    //  this.context.statusRenderer.clearLoadingIndicator(this.domElement);

    this.state = 
      items       : listItems,
      columns     : listColumns,
      compactMode : false
    ;
  

  public render(): JSX.Element 
    const  items, columns, compactMode  = this.state;

    return (
      <div>
        <div className='ms-SearchBoxSmall'>
          <CommandBar
            isSearchBoxVisible= true 
            items= [] 
            farItems= this.listFarItems 
          />
        </div>
        <br />
        <div>
          <DetailsList
            items= items 
            columns= columns 
            compact= compactMode 
            layoutMode= DetailsListLayoutMode.justified 
            selectionMode= SelectionMode.none 
            onColumnHeaderClick= this._onColumnClick 
          />
        </div>
      </div>
    );
  

  public async queryLists() 
    await sp.web.lists
      .filter("Hidden eq false")
      .expand('RootFolder')
      .get()
      .then( response => 
        response.forEach( (item, index) => 
          var newData = new Date(item.LastItemModifiedDate).toLocaleDateString() + ' ' + new Date(item.LastItemModifiedDate).toLocaleTimeString();
          listItems.push(
            "ID"       : index,
            "URL"      : item.RootFolder.ServerRelativeUrl,
            "Icon"     : item.BaseTemplate,
            "Title"    : item.Title,
            "Total"    : item.ItemCount,
            "Modified" : newData
          );

        );
      );
    

【问题讨论】:

【参考方案1】:

我找到了问题的答案!首先,我放弃了 displayLoadingIndicator 以支持使用 的更简单的解决方案:

const loadingStatus: JSX.Element = this.state.loading ? <div style=margin: '0 auto'><Spinner label='Loading libraries and lists...' /></div> : <div/>;

然后在组件state中添加了一个名为loading的新字段来监控queryLists()的完成情况,一旦这个方法返回所有结果,组件 state 被更新,** 将在下一次渲染时被丢弃。

事实证明我的代码是正确的 :) 我的问题出在组件 - 您必须更新组件的属性 key 才能使其内容“更新”页面,所以我的代码现在如下:

  public render(): React.ReactElement<IPnPListsProps> 
    const loadingStatus: JSX.Element = this.state.loading ? <div style=margin: '0 auto'><Spinner label='Loading libraries and lists...' /></div> : <div/>;
    return (
      <div>
        <div className='ms-SearchBoxSmall'>
          <CommandBar
            isSearchBoxVisible= true 
            items= [] 
          />
        </div>
        <br />
        <div>
          <DetailsList          
            key= new Date().getTime()    // this will get the component refreshed everytime!
            items= listItems 
            columns= listColumns 
            layoutMode= DetailsListLayoutMode.justified 
            selectionMode= SelectionMode.none 
          />
        </div>
        loadingStatus
      </div>
    );
  

  public async queryLists() 
    await sp.web.lists
      .filter("Hidden eq false")
      .expand('RootFolder')
      .get()
      .then( response => 
        response.forEach( (item, index) => 
          var newData = new Date(item.LastItemModifiedDate).toLocaleDateString() + ' ' + new Date(item.LastItemModifiedDate).toLocaleTimeString();
          listItems.push(
            "ID"       : index,
            "URL"      : item.RootFolder.ServerRelativeUrl,
            "Icon"     : item.BaseTemplate,
            "Title"    : item.Title,
            "Total"    : item.ItemCount,
            "Modified" : newData
          );
        this.setState(
          items   : listItems,
          loading : false
        );
      );
   

【讨论】:

以上是关于SPFX - 长时间间隔后刷新 Web 部件的主要内容,如果未能解决你的问题,请参考以下文章

在 SPFx Web 部件内显示库视图

SPFx Web 部件的 CSS 适用于它但不适用于页面的其余部分?

在现代站点中添加 SPFx webpart 时的 Javascript

手机怎么自动刷新网页

如何在单个 spfx 解决方案中创建两个 webpart?

如何在SPFX经典视图中创建自定义母版页