Reactjs 更新行时如何刷新Fabric Ui Details列表

Reactjs 更新行时如何刷新Fabric Ui Details列表,reactjs,components,office-ui-fabric,Reactjs,Components,Office Ui Fabric,我正在尝试创建fabric ui detailsList组件。这个组件应该简单地表示我在数据库中拥有的内容,并且可以为每一行更新特定的列值。要进行更新,每行都应该有一个fabric ui PrimaryButton。 我还在服务器中创建了两个API(GET和POST)。GET请求将向react应用程序返回将显示的所有资源,POST(单击特定行的PrimaryButton称为whne)将在参数中包含行的Id,并将更新列的值 我创建了一个根组件:App,它加载DetailsList并调用getapi

我正在尝试创建fabric ui detailsList组件。这个组件应该简单地表示我在数据库中拥有的内容,并且可以为每一行更新特定的列值。要进行更新,每行都应该有一个fabric ui PrimaryButton。 我还在服务器中创建了两个API(GET和POST)。GET请求将向react应用程序返回将显示的所有资源,POST(单击特定行的PrimaryButton称为whne)将在参数中包含行的Id,并将更新列的值

我创建了一个根组件:App,它加载DetailsList并调用getapi来获取所有资源并显示它们。我还创建了一个子组件:ResolveButton,它将为根组件的详细信息列表中的每一行调用

App.tsx:

import * as React from 'react';
import ResolveButton from './ResolveButton';


export interface IDetailsListCustomColumnsExampleState {
  sortedItems?: any[];
  columns?: IColumn[];
  hasError: boolean;
}


export class App extends React.Component<{}, IDetailsListCustomColumnsExampleState> {
  public constructor(props: {}) {
    super(props);

    this.state = {
      columns: [],
      hasError:false,
      sortedItems: []
    };
    this._renderItemColumn=this._renderItemColumn.bind(this);
    this.changeStatus = this.changeStatus.bind(this);
  }
  public componentDidCatch() {
    // Display fallback UI
    this.setState({ hasError: true });
  }
  public componentDidMount(){
    this.fetchResult()
  }
  public render() {
    const { sortedItems, columns } = this.state;
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }
    else{
      return (
        <DetailsList
          items={sortedItems as any[]}
          setKey="set"
          columns={columns}
          onRenderItemColumn={this._renderItemColumn}
          onColumnHeaderClick={this.onColumnClick}
          onItemInvoked={this._onItemInvoked}
          onColumnHeaderContextMenu={this._onColumnHeaderContextMenu}
          ariaLabelForSelectionColumn="Toggle selection"
          ariaLabelForSelectAllCheckbox="Toggle selection for all items"
        />
      );
    }

  }
  public changeStatus (itemId:React.ReactText){
    // TODO : call the POST API to update the status
    const { sortedItems } = this.state;
    const resolvedKey='Status';
    const idKey='Id';

    sortedItems!.map(ite => {
      if(ite[idKey] === itemId){
          ite[resolvedKey] = 3;
      }
      return ite;
    })
    this.setState({
      sortedItems
    });
  }
  private fetchResult = () =>{
    fetch('https://localhost:44329/home')
    .then((response) => response.json())
    .then(json => this.setState({ columns: _buildColumns(json),
    sortedItems: json })).catch((error) => 
    { 
      this.componentDidCatch()
    })
  }

  private onColumnClick = (event: React.MouseEvent<HTMLElement>, column: IColumn): void => {
    const { columns } = this.state;
    let { sortedItems } = this.state;
    let isSortedDescending = column.isSortedDescending;

    // If we've sorted this column, flip it.
    if (column.isSorted) {
      isSortedDescending = !isSortedDescending;
    }

    // Sort the items.
    sortedItems = sortedItems!.concat([]).sort((a, b) => {
      const firstValue = a[column.fieldName || ''];
      const secondValue = b[column.fieldName || ''];

      if (isSortedDescending) {
        return firstValue > secondValue ? -1 : 1;
      } else {
        return firstValue > secondValue ? 1 : -1;
      }
    });

    // Reset the items and columns to match the state.
    this.setState({
      columns: columns!.map(col => {
        col.isSorted = col.key === column.key;

        if (col.isSorted) {
          col.isSortedDescending = isSortedDescending;
        }

        return col;
      }),
      sortedItems      
    });
  };

  private _onColumnHeaderContextMenu(column: IColumn | undefined, ev: React.MouseEvent<HTMLElement> | undefined): void {

    alert(`column ${column!.key} contextmenu opened.`);
  }

  private _onItemInvoked(item: any, index: number | undefined): void {
    alert(`Item ${item.name} at index ${index} has been invoked.`);
  }

private _renderItemColumn(item: any, index: number, column: IColumn) {

  const fieldContent = item[column.fieldName || ''];

  const crisisColor = {
    1: 'Red',
    2: 'Orange',
    3: 'Yellow',
    4: 'Green'
  }
  const crisis = {
    1: 'Crise',
    2: 'Haute',
    3: 'Moyenne',
    4: 'Basse'
  }
  const statusColor = {
    1: 'Black',
    2: 'Black',
    3: 'Green'
  } 
  const status = {
    1: 'Ouvert',
    2: 'En cours',
    3: 'Résolu'
  }
  const resolvedKey='Status';
  const isResolved = item[resolvedKey]===3;
  switch (column.key) {
    case 'Status':
      return (
        <span data-selection-disabled={true} style={{ color: statusColor[fieldContent], height: '100%', display: 'block' }}>
          {status[fieldContent]}
        </span>
      );

    case 'Criticity':
      return (
        <span data-selection-disabled={true} style={{ color: crisisColor[fieldContent], height: '100%', display: 'block' }}>
          {crisis[fieldContent]}
        </span>
      );
    case 'Creator':
      return(
        <div>
        <img src="https://img.mobiscroll.com/demos/BMW_logo.png" width="30px" height="30px" style={{verticalAlign: 'middle', display:'inline' }}/>
        <p style={{verticalAlign: 'middle', display:'inline' , paddingLeft:'10px'}}>{fieldContent}</p>
        </div>
      ); 
    case 'AssignedTo':
      return(
        <div>
        <img src="https://img.mobiscroll.com/demos/BMW_logo.png" width="30px" height="30px" style={{verticalAlign: 'middle', display:'inline' }}/>
        <p style={{verticalAlign: 'middle', display:'inline' , paddingLeft:'10px'}}>{fieldContent}</p>
        </div>
      );

    case 'Id':
      return(
        // tslint:disable-next-line jsx-no-lambda
        <ResolveButton disabled={isResolved} uniqueId={fieldContent} changeStatus={ ()=>this.changeStatus(fieldContent)} /> 
      );

    default:
      return <span>{fieldContent}</span>;
  }
}
}
function _buildColumns(json:any[]) {
  const columns = buildColumns(json);
  return columns;
}

export default App;
import*as React from'React';
从“/ResolveButton”导入ResolveButton;
导出接口idetailslistcustomcolumnsamplestate{
sortedItems?:任何[];
列?:IColumn[];
hasrerror:布尔型;
}
导出类应用程序扩展React.Component{
公共构造函数(props:{}){
超级(道具);
此.state={
列:[],
错误:错,
分类数据项:[]
};
this.\u renderItemColumn=this.\u renderItemColumn.bind(this);
this.changeStatus=this.changeStatus.bind(this);
}
公共组件didcatch(){
//显示回退用户界面
this.setState({hasError:true});
}
公共组件didmount(){
this.fetchResult()
}
公共渲染(){
const{sortedItems,columns}=this.state;
if(this.state.hasError){
//您可以呈现任何自定义回退UI
返回出了问题的地方。;
}
否则{
返回(
);
}
}
公共变更状态(itemId:React.ReactText){
//TODO:调用POST API以更新状态
const{sortedItems}=this.state;
const resolvedKey='Status';
常量idKey='Id';
sortedItems!.map(站点=>{
if(ite[idKey]==itemId){
ite[resolvedKey]=3;
}
返回矿;
})
这是我的国家({
分类数据
});
}
私有fetchResult=()=>{
取('https://localhost:44329/home')
.then((response)=>response.json())
.then(json=>this.setState({columns:_buildColumns(json)),
sortedItems:json})。catch((错误)=>
{ 
this.componentDidCatch()
})
}
私有onColumnClick=(事件:React.MouseEvent,列:IColumn):void=>{
const{columns}=this.state;
设{sortedItems}=this.state;
设IsSortedescending=column.IsSortedescending;
//如果我们已经对该列进行了排序,请将其翻转。
如果(列ISORTED){
IsSortedescending=!IsSortedescending;
}
//对项目进行排序。
sortedItems=sortedItems!.concat([]).sort((a,b)=>{
const firstValue=a[column.fieldName | |“”;
const secondValue=b[column.fieldName | |“”;
如果(isSortedDescending){
返回第一个值>第二个值?-1:1;
}否则{
返回第一个值>第二个值?1:-1;
}
});
//重置项目和列以匹配状态。
这是我的国家({
列:列!.map(列=>{
col.isSorted=col.key==column.key;
如果(分类列){
col.IsSortedescending=IsSortedescending;
}
返回列;
}),
分类数据
});
};
private _onColumnHeaderContextMenu(列:IColumn |未定义,ev:React.MouseEvent |未定义):无效{
警报(`column${column!.key}上下文菜单已打开。`);
}
private|u minvoked(项目:任意,索引:编号|未定义):void{
警报(`Item${Item.name}在索引${index}处已被调用。`);
}
private _renderItemColumn(项:any,索引:number,列:IColumn){
const fieldContent=项[column.fieldName | |'''];
常数CrisColor={
1:‘红色’,
2:‘橙色’,
3:‘黄色’,
4:‘绿色’
}
常数危机={
1:‘Crise’,
2:‘高级’,
3:‘莫耶恩’,
4:‘贝斯’
}
常量状态颜色={
1:‘黑色’,
2:‘黑色’,
3:‘绿色’
} 
常数状态={
1:‘Ouvert’,
2:‘当然’,
3:“Résolu”
}
const resolvedKey='Status';
const isResolved=项目[resolvedKey]==3;
开关(column.key){
案例“状态”:
返回(
{状态[fieldContent]}
);
案例“临界性”:
返回(
{危机[fieldContent]}
);
案例“创造者”:
返回(

{fieldContent}

); “分配到”案例: 返回(

{fieldContent}

); 案件编号: 返回( //tslint:禁用下一行jsx no lambda this.changeStatus(fieldContent)}/> ); 违约: 返回{fieldContent}; } } } 函数_buildColumns(json:any[]){ const columns=buildColumns(json); 返回列; } 导出默认应用程序;
ResolveButton.tsx

import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
import * as React from 'react';

export interface IHandleChange {
    changeStatus: ()=>void;
    disabled:boolean;
    uniqueId:string| number;
}
export class ResolveButton extends React.Component<IHandleChange, {}> {
    constructor(props:any) {

        super(props);
    }
    public render(): JSX.Element {
        return (
            <div>
                {
                    !this.props.disabled && 
                    <PrimaryButton
                        data-automation-id="test"
                        text="Résolu"
                        onClick={this.props.changeStatus}
                        allowDisabledFocus={true}
                    />
                }
            </div>
        );
    }
}
export default ResolveButton;
从“office ui fabric react/lib/Button”导入{PrimaryButton};
从“React”导入*作为React;
导出接口IHandleChange{
变更状态:()=>作废;
禁用:布尔值;
唯一标识:字符串|编号;
}
导出类ResolveButton扩展React.Component{
构造器(道具:任何){
超级(道具);
}
public render():JSX.Element{
返回(
{
!this.props.disabled&&
}
);
}
}
导出默认解析按钮;
正如您在my App.tsx中看到的,当列键为“Id”时,我创建了ResolveButton组件。 我的问题是,当点击按钮时,数据库中的数据将被更新,但react应用程序中显示的是al
class ResolveButton extends React.Component<IButtonProps, {}> {
  async handleClick() {
     const response = await fetch('https://localhost:44329/home')
     const json = await response.json();

     if (this.props.onResolved) {
         this.props.onResolved(json);
     }
  }
}
class App extends React.Component<{}, IDetailsListCustomColumnsExampleState> {
  …
   <ResolveButton
        disabled={isResolved}
        uniqueId={fieldContent}
        onResolved={(data) => setState({'sortedItems': data})
   />
  …
}