Typescript 重构react组件使其更短

Typescript 重构react组件使其更短,typescript,design-patterns,Typescript,Design Patterns,我有以下代码,但首先是解释。 我正在使用名为“详细信息列表”的REACTJS Office UI组件: 我希望我的应用程序能够呈现来自任何类型Sharepoint列表的信息,而不管源文件中有哪些列。为此,我尝试实现工厂方法设计模式,如下所示: export interface IListItem { [key: string]: any; id: string; title: string; modified: Date; created: Date;

我有以下代码,但首先是解释。 我正在使用名为“详细信息列表”的REACTJS Office UI组件:

我希望我的应用程序能够呈现来自任何类型Sharepoint列表的信息,而不管源文件中有哪些列。为此,我尝试实现工厂方法设计模式,如下所示:

export  interface IListItem {
    [key: string]: any;
    id: string;
    title: string;
    modified: Date;
    created: Date;
    modifiedby: string;
    createdby: string;    
}

import {IListItem} from './IListItem';

export interface  IAnnouncementListItem extends IListItem {
    announcementBody: string;
    expiryDate: Date;  
}

import {IListItem} from './IListItem';

export interface IDirectoryListItem extends IListItem {
        firstName: string;
        lastName: string;
        mobileNumber: string;
        internalNumber: string;  
}


import {IListItem} from './IListItem';

export interface  INewsListItem extends IListItem {
    newsheader: string;
    newsbody: string;
    expiryDate: Date;
}

import { IListItem } from './models/IListItem';
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
export  interface IFactory{
    getItems(requester: SPHttpClient, siteUrl: string, listName: string): IListItem[];
}

import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
import { IWebPartContext } from '@microsoft/sp-webpart-base';
import { IListItem} from './models/IListItem';
import { IFactory } from './IFactory';
import { INewsListItem } from './models/INewsListItem';
import { IDirectoryListItem } from './models/IDirectoryListItem';
import { IAnnouncementListItem } from './models/IAnnouncementListItem';

export class ListItemFactory implements IFactory{   
    getItems(requester: SPHttpClient, siteUrl: string, listName: string): IListItem[] {
        switch(listName) {
            case 'List':
                let items: IListItem[];
                requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`,
                SPHttpClient.configurations.v1,
                {
                    headers: {
                    'Accept': 'application/json;odata=nometadata',
                    'odata-version': ''
                    }
                })
                .then((response: SPHttpClientResponse): Promise<{ value: IListItem[] }> => {
                    return response.json();
                })
                .then((response: { value: IListItem[] }): void => {
                    items= response.value;
                });
                return items;
            case 'News':
                let newsitems: INewsListItem[];
                requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`,
                SPHttpClient.configurations.v1,
                {
                    headers: {
                    'Accept': 'application/json;odata=nometadata',
                    'odata-version': ''
                    }
                })
                .then((response: SPHttpClientResponse): Promise<{ value: INewsListItem[] }> => {
                    return response.json();
                })
                .then((response: { value: INewsListItem[] }): void => {
                    newsitems= response.value;
                });
                return newsitems;
            case 'Announcements':
                let announcementitems: IAnnouncementListItem[];
                requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`,
                SPHttpClient.configurations.v1,
                {
                    headers: {
                    'Accept': 'application/json;odata=nometadata',
                    'odata-version': ''
                    }
                })
                .then((response: SPHttpClientResponse): Promise<{ value: IAnnouncementListItem[] }> => {
                    return response.json();
                })
                .then((response: { value: IAnnouncementListItem[] }): void => {
                    announcementitems= response.value;
                });
                return announcementitems;
            case 'Directory':
                let directoryitems: IDirectoryListItem[];
                requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`,
                SPHttpClient.configurations.v1,
                {
                    headers: {
                    'Accept': 'application/json;odata=nometadata',
                    'odata-version': ''
                    }
                })
                .then((response: SPHttpClientResponse): Promise<{ value: IDirectoryListItem[] }> => {
                    return response.json();
                })
                .then((response: { value: IDirectoryListItem[] }): void => {
                    items= response.value;
                });
                return directoryitems;
            default:
                return null;
        }
      }
} 
    /* public getItems(requester: SPHttpClient, siteUrl: string, listName: string): IListItem[] {
        let items: IListItem[];
        requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`,
        SPHttpClient.configurations.v1,
        {
            headers: {
            'Accept': 'application/json;odata=nometadata',
            'odata-version': ''
            }
        })
        .then((response: SPHttpClientResponse): Promise<{ value: IListItem[] }> => {
            return response.json();
        })
        .then((response: { value: IListItem[] }): void => {
            items= response.value;
        });
        return items;
    } */
}
import * as React from 'react';
import styles from './FactoryMethod.module.scss';
import { IFactoryMethodProps } from './IFactoryMethodProps';
import { 
  IDetailsListItemState,  
  IDetailsNewsListItemState,
  IDetailsDirectoryListItemState,
  IDetailsAnnouncementListItemState,
  IFactoryMethodState
} from './IFactoryMethodState';
import { IListItem } from './models/IListItem';
import { IAnnouncementListItem } from './models/IAnnouncementListItem';
import { INewsListItem } from './models/INewsListItem';
import { IDirectoryListItem } from './models/IDirectoryListItem';

import { escape } from '@microsoft/sp-lodash-subset';
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
import { ListItemFactory} from './ListItemFactory';
import { TextField } from 'office-ui-fabric-react/lib/TextField';
import {
  DetailsList,
  DetailsListLayoutMode,
  Selection,
  IColumn
} from 'office-ui-fabric-react/lib/DetailsList';
import { MarqueeSelection } from 'office-ui-fabric-react/lib/MarqueeSelection';
import { autobind } from 'office-ui-fabric-react/lib/Utilities';

let _columns = [
  {
    key: 'column1',
    name: 'Name',
    fieldName: 'name',
    minWidth: 100,
    maxWidth: 200,
    isResizable: true
  },
  {
    key: 'column2',
    name: 'Value',
    fieldName: 'value',
    minWidth: 100,
    maxWidth: 200,
    isResizable: true
  },
];

export default class FactoryMethod extends React.Component<any, IFactoryMethodState> {
  private listItemEntityTypeName: string = undefined;
  private _selection: Selection;

  constructor(props: IFactoryMethodProps, state: any) {
    super(props);

    //Initialize state
    this.state = {
      type: 'ListItem',
      status: this.listNotConfigured(this.props) ? 'Please configure list in Web Part properties' : 'Ready',
      DetailsListItemState:{
        columns:[],
        items:[]
      },
      DetailsNewsListItemState:{
        columns:[],
        items:[]
      },
      DetailsDirectoryListItemState:{
        columns:[],
        items:[]
      },
      DetailsAnnouncementListItemState:{
        columns:[],
        items:[]
      },
    };
  }

  public componentWillReceiveProps(nextProps: IFactoryMethodProps): void {
    this.listItemEntityTypeName = undefined;
    //Initialize state
    this.state = {
      type: 'ListItem',
      status: this.listNotConfigured(this.props) ? 'Please configure list in Web Part properties' : 'Ready',
      DetailsListItemState:{
        columns:[],
        items:[]
      },
      DetailsNewsListItemState:{
        columns:[],
        items:[]
      },
      DetailsDirectoryListItemState:{
        columns:[],
        items:[]
      },
      DetailsAnnouncementListItemState:{
        columns:[],
        items:[]
      },
    };
  }

  public render(): React.ReactElement<IFactoryMethodProps> {
    let { type, 
      status, 
      DetailsListItemState, 
      DetailsNewsListItemState, 
      DetailsDirectoryListItemState, 
      DetailsAnnouncementListItemState } = this.state;

        switch(this.props.listName)
        {
          case "List":
            return (
              <div>
                <MarqueeSelection selection={ this._selection }>
                  <DetailsList
                    items={ DetailsListItemState.items }
                    columns={ DetailsListItemState.columns }
                    setKey='set'
                    layoutMode={ DetailsListLayoutMode.fixedColumns }
                    selection={ this._selection }
                    selectionPreservedOnEmptyClick={ true }                
                    compact={ true }
                  />
                </MarqueeSelection>
              </div>
            );         
          case "Announcements":
            return (
              <div>
                <MarqueeSelection selection={ this._selection }>
                  <DetailsList
                    items={ DetailsAnnouncementListItemState.items }
                    columns={ DetailsAnnouncementListItemState.columns }
                    setKey='set'
                    layoutMode={ DetailsListLayoutMode.fixedColumns }
                    selection={ this._selection }
                    selectionPreservedOnEmptyClick={ true }                
                    compact={ true }
                  />
                </MarqueeSelection>
              </div>
            );
        case "News":
          return (
            <div>
              <MarqueeSelection selection={ this._selection }>
                <DetailsList
                  items={ DetailsNewsListItemState.items }
                  columns={ DetailsNewsListItemState.columns }
                  setKey='set'
                  layoutMode={ DetailsListLayoutMode.fixedColumns }
                  selection={ this._selection }
                  selectionPreservedOnEmptyClick={ true }                
                  compact={ true }
                />
              </MarqueeSelection>
            </div>
          );
        case "Directory":
          return (
            <div>
              <MarqueeSelection selection={ this._selection }>
                <DetailsList
                  items={ DetailsDirectoryListItemState.items }
                  columns={ DetailsDirectoryListItemState.columns }
                  setKey='set'
                  layoutMode={ DetailsListLayoutMode.fixedColumns }
                  selection={ this._selection }
                  selectionPreservedOnEmptyClick={ true }                
                  compact={ true }
                />
              </MarqueeSelection>
            </div>
          );
        default : 
          break;
      }
  }

  private readItems(): void {
    this.setState({
      status: 'Loading all items...'
    });
    let factory = new  ListItemFactory();

    //Here its where we actually use the pattern to make our coding easier.
    switch(this.props.listName)
    {
      case "List":
        let listItems  = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName);  
        this.setState({
          status: `Successfully loaded ${listItems.length} items`,
          DetailsListItemState : {
            items: listItems,
            columns: [
            ]
          }
        });      
        break;
      case "Announcements":
        let announcementlistItems  = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName) as IAnnouncementListItem[];  
        this.setState({
          status: `Successfully loaded ${listItems.length} items`,
          DetailsAnnouncementListItemState : {
            items: announcementlistItems,
            columns: []
          }
        });          
        break;
      case "News":
        let newsListItems  = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName) as INewsListItem[];  
        this.setState({
          status: `Successfully loaded ${listItems.length} items`,
          DetailsNewsListItemState : {
            items: newsListItems,
            columns: []
          }
        });      
        break;
      case "Directory":
        let directoryListItems  = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName) as IDirectoryListItem[];  
        this.setState({
          status: `Successfully loaded ${listItems.length} items`,
          DetailsDirectoryListItemState : {
            items: directoryListItems,
            columns: []
          }
        });   
        break;
      default : 
        break;
    }    
  }

  private _getSelectionDetails(): string {
    let selectionCount = this._selection.getSelectedCount();

    switch (selectionCount) {
      case 0:
        return 'No items selected';
      case 1:
        return '1 item selected: ' + (this._selection.getSelection()[0] as any).name;
      default:
        return `${selectionCount} items selected`;
    }
  }

  private listNotConfigured(props: IFactoryMethodProps): boolean {
    return props.listName === undefined ||
      props.listName === null ||
      props.listName.length === 0;
  }


}
正如您所看到的,我有不同类型的结果,所以我封装了IfactoryMethodState的信息

现在在组件中,我使用它如下所示:

export  interface IListItem {
    [key: string]: any;
    id: string;
    title: string;
    modified: Date;
    created: Date;
    modifiedby: string;
    createdby: string;    
}

import {IListItem} from './IListItem';

export interface  IAnnouncementListItem extends IListItem {
    announcementBody: string;
    expiryDate: Date;  
}

import {IListItem} from './IListItem';

export interface IDirectoryListItem extends IListItem {
        firstName: string;
        lastName: string;
        mobileNumber: string;
        internalNumber: string;  
}


import {IListItem} from './IListItem';

export interface  INewsListItem extends IListItem {
    newsheader: string;
    newsbody: string;
    expiryDate: Date;
}

import { IListItem } from './models/IListItem';
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
export  interface IFactory{
    getItems(requester: SPHttpClient, siteUrl: string, listName: string): IListItem[];
}

import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
import { IWebPartContext } from '@microsoft/sp-webpart-base';
import { IListItem} from './models/IListItem';
import { IFactory } from './IFactory';
import { INewsListItem } from './models/INewsListItem';
import { IDirectoryListItem } from './models/IDirectoryListItem';
import { IAnnouncementListItem } from './models/IAnnouncementListItem';

export class ListItemFactory implements IFactory{   
    getItems(requester: SPHttpClient, siteUrl: string, listName: string): IListItem[] {
        switch(listName) {
            case 'List':
                let items: IListItem[];
                requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`,
                SPHttpClient.configurations.v1,
                {
                    headers: {
                    'Accept': 'application/json;odata=nometadata',
                    'odata-version': ''
                    }
                })
                .then((response: SPHttpClientResponse): Promise<{ value: IListItem[] }> => {
                    return response.json();
                })
                .then((response: { value: IListItem[] }): void => {
                    items= response.value;
                });
                return items;
            case 'News':
                let newsitems: INewsListItem[];
                requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`,
                SPHttpClient.configurations.v1,
                {
                    headers: {
                    'Accept': 'application/json;odata=nometadata',
                    'odata-version': ''
                    }
                })
                .then((response: SPHttpClientResponse): Promise<{ value: INewsListItem[] }> => {
                    return response.json();
                })
                .then((response: { value: INewsListItem[] }): void => {
                    newsitems= response.value;
                });
                return newsitems;
            case 'Announcements':
                let announcementitems: IAnnouncementListItem[];
                requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`,
                SPHttpClient.configurations.v1,
                {
                    headers: {
                    'Accept': 'application/json;odata=nometadata',
                    'odata-version': ''
                    }
                })
                .then((response: SPHttpClientResponse): Promise<{ value: IAnnouncementListItem[] }> => {
                    return response.json();
                })
                .then((response: { value: IAnnouncementListItem[] }): void => {
                    announcementitems= response.value;
                });
                return announcementitems;
            case 'Directory':
                let directoryitems: IDirectoryListItem[];
                requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`,
                SPHttpClient.configurations.v1,
                {
                    headers: {
                    'Accept': 'application/json;odata=nometadata',
                    'odata-version': ''
                    }
                })
                .then((response: SPHttpClientResponse): Promise<{ value: IDirectoryListItem[] }> => {
                    return response.json();
                })
                .then((response: { value: IDirectoryListItem[] }): void => {
                    items= response.value;
                });
                return directoryitems;
            default:
                return null;
        }
      }
} 
    /* public getItems(requester: SPHttpClient, siteUrl: string, listName: string): IListItem[] {
        let items: IListItem[];
        requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`,
        SPHttpClient.configurations.v1,
        {
            headers: {
            'Accept': 'application/json;odata=nometadata',
            'odata-version': ''
            }
        })
        .then((response: SPHttpClientResponse): Promise<{ value: IListItem[] }> => {
            return response.json();
        })
        .then((response: { value: IListItem[] }): void => {
            items= response.value;
        });
        return items;
    } */
}
import * as React from 'react';
import styles from './FactoryMethod.module.scss';
import { IFactoryMethodProps } from './IFactoryMethodProps';
import { 
  IDetailsListItemState,  
  IDetailsNewsListItemState,
  IDetailsDirectoryListItemState,
  IDetailsAnnouncementListItemState,
  IFactoryMethodState
} from './IFactoryMethodState';
import { IListItem } from './models/IListItem';
import { IAnnouncementListItem } from './models/IAnnouncementListItem';
import { INewsListItem } from './models/INewsListItem';
import { IDirectoryListItem } from './models/IDirectoryListItem';

import { escape } from '@microsoft/sp-lodash-subset';
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
import { ListItemFactory} from './ListItemFactory';
import { TextField } from 'office-ui-fabric-react/lib/TextField';
import {
  DetailsList,
  DetailsListLayoutMode,
  Selection,
  IColumn
} from 'office-ui-fabric-react/lib/DetailsList';
import { MarqueeSelection } from 'office-ui-fabric-react/lib/MarqueeSelection';
import { autobind } from 'office-ui-fabric-react/lib/Utilities';

let _columns = [
  {
    key: 'column1',
    name: 'Name',
    fieldName: 'name',
    minWidth: 100,
    maxWidth: 200,
    isResizable: true
  },
  {
    key: 'column2',
    name: 'Value',
    fieldName: 'value',
    minWidth: 100,
    maxWidth: 200,
    isResizable: true
  },
];

export default class FactoryMethod extends React.Component<any, IFactoryMethodState> {
  private listItemEntityTypeName: string = undefined;
  private _selection: Selection;

  constructor(props: IFactoryMethodProps, state: any) {
    super(props);

    //Initialize state
    this.state = {
      type: 'ListItem',
      status: this.listNotConfigured(this.props) ? 'Please configure list in Web Part properties' : 'Ready',
      DetailsListItemState:{
        columns:[],
        items:[]
      },
      DetailsNewsListItemState:{
        columns:[],
        items:[]
      },
      DetailsDirectoryListItemState:{
        columns:[],
        items:[]
      },
      DetailsAnnouncementListItemState:{
        columns:[],
        items:[]
      },
    };
  }

  public componentWillReceiveProps(nextProps: IFactoryMethodProps): void {
    this.listItemEntityTypeName = undefined;
    //Initialize state
    this.state = {
      type: 'ListItem',
      status: this.listNotConfigured(this.props) ? 'Please configure list in Web Part properties' : 'Ready',
      DetailsListItemState:{
        columns:[],
        items:[]
      },
      DetailsNewsListItemState:{
        columns:[],
        items:[]
      },
      DetailsDirectoryListItemState:{
        columns:[],
        items:[]
      },
      DetailsAnnouncementListItemState:{
        columns:[],
        items:[]
      },
    };
  }

  public render(): React.ReactElement<IFactoryMethodProps> {
    let { type, 
      status, 
      DetailsListItemState, 
      DetailsNewsListItemState, 
      DetailsDirectoryListItemState, 
      DetailsAnnouncementListItemState } = this.state;

        switch(this.props.listName)
        {
          case "List":
            return (
              <div>
                <MarqueeSelection selection={ this._selection }>
                  <DetailsList
                    items={ DetailsListItemState.items }
                    columns={ DetailsListItemState.columns }
                    setKey='set'
                    layoutMode={ DetailsListLayoutMode.fixedColumns }
                    selection={ this._selection }
                    selectionPreservedOnEmptyClick={ true }                
                    compact={ true }
                  />
                </MarqueeSelection>
              </div>
            );         
          case "Announcements":
            return (
              <div>
                <MarqueeSelection selection={ this._selection }>
                  <DetailsList
                    items={ DetailsAnnouncementListItemState.items }
                    columns={ DetailsAnnouncementListItemState.columns }
                    setKey='set'
                    layoutMode={ DetailsListLayoutMode.fixedColumns }
                    selection={ this._selection }
                    selectionPreservedOnEmptyClick={ true }                
                    compact={ true }
                  />
                </MarqueeSelection>
              </div>
            );
        case "News":
          return (
            <div>
              <MarqueeSelection selection={ this._selection }>
                <DetailsList
                  items={ DetailsNewsListItemState.items }
                  columns={ DetailsNewsListItemState.columns }
                  setKey='set'
                  layoutMode={ DetailsListLayoutMode.fixedColumns }
                  selection={ this._selection }
                  selectionPreservedOnEmptyClick={ true }                
                  compact={ true }
                />
              </MarqueeSelection>
            </div>
          );
        case "Directory":
          return (
            <div>
              <MarqueeSelection selection={ this._selection }>
                <DetailsList
                  items={ DetailsDirectoryListItemState.items }
                  columns={ DetailsDirectoryListItemState.columns }
                  setKey='set'
                  layoutMode={ DetailsListLayoutMode.fixedColumns }
                  selection={ this._selection }
                  selectionPreservedOnEmptyClick={ true }                
                  compact={ true }
                />
              </MarqueeSelection>
            </div>
          );
        default : 
          break;
      }
  }

  private readItems(): void {
    this.setState({
      status: 'Loading all items...'
    });
    let factory = new  ListItemFactory();

    //Here its where we actually use the pattern to make our coding easier.
    switch(this.props.listName)
    {
      case "List":
        let listItems  = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName);  
        this.setState({
          status: `Successfully loaded ${listItems.length} items`,
          DetailsListItemState : {
            items: listItems,
            columns: [
            ]
          }
        });      
        break;
      case "Announcements":
        let announcementlistItems  = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName) as IAnnouncementListItem[];  
        this.setState({
          status: `Successfully loaded ${listItems.length} items`,
          DetailsAnnouncementListItemState : {
            items: announcementlistItems,
            columns: []
          }
        });          
        break;
      case "News":
        let newsListItems  = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName) as INewsListItem[];  
        this.setState({
          status: `Successfully loaded ${listItems.length} items`,
          DetailsNewsListItemState : {
            items: newsListItems,
            columns: []
          }
        });      
        break;
      case "Directory":
        let directoryListItems  = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName) as IDirectoryListItem[];  
        this.setState({
          status: `Successfully loaded ${listItems.length} items`,
          DetailsDirectoryListItemState : {
            items: directoryListItems,
            columns: []
          }
        });   
        break;
      default : 
        break;
    }    
  }

  private _getSelectionDetails(): string {
    let selectionCount = this._selection.getSelectedCount();

    switch (selectionCount) {
      case 0:
        return 'No items selected';
      case 1:
        return '1 item selected: ' + (this._selection.getSelection()[0] as any).name;
      default:
        return `${selectionCount} items selected`;
    }
  }

  private listNotConfigured(props: IFactoryMethodProps): boolean {
    return props.listName === undefined ||
      props.listName === null ||
      props.listName.length === 0;
  }


}
import*as React from'React';
从“./FactoryMethod.module.scss”导入样式;
从“/IFactoryMethodOps”导入{IFactoryMethodOps};
导入{
理想状态,
IDetailsNewsListItemState,
IDetailsDirectoryListItemState,
IdetailsAnonounceListItemState,
IFactoryMethodState
}来自“/IFactoryMethodState”;
从“./models/IListItem”导入{IListItem};
从“./models/IANNouncedListItem”导入{IANNouncedListItem};
从“./models/InewListItem”导入{InewListItem};
从“./models/IDirectorylitem”导入{IDirectorylitem};
从'@microsoft/sp lodash subset'导入{escape};
从“@microsoft/sp http”导入{SPHttpClient,SPHttpClientResponse};
从“/ListItemFactory”导入{ListItemFactory};
从“office ui fabric react/lib/TextField”导入{TextField};
进口{
详细列表,
DetailsListLayoutMode,
选择,
IColumn
}来自“office ui fabric react/lib/DetailsList”;
从“office ui fabric react/lib/MarqueeSelection”导入{MarqueeSelection};
从“office ui fabric react/lib/Utilities”导入{autobind};
设_列=[
{
键:“column1”,
姓名:'姓名',
fieldName:'名称',
最小宽度:100,
最大宽度:200,
isResizable:对
},
{
键:“column2”,
名称:“值”,
字段名:“值”,
最小宽度:100,
最大宽度:200,
isResizable:对
},
];
导出默认类FactoryMethod扩展React.Component{
私有listItemEntityTypeName:string=未定义;
私人选择:选择;
构造函数(道具:ifactorymethodrops,状态:any){
超级(道具);
//初始化状态
此.state={
键入:“ListItem”,
状态:this.listNotConfigured(this.props)“‘请在Web部件属性中配置列表’:‘就绪’,
详细信息机构状态:{
列:[],
项目:[]
},
详细信息WSListItemState:{
列:[],
项目:[]
},
详细信息目录列表状态:{
列:[],
项目:[]
},
详细信息列表项状态:{
列:[],
项目:[]
},
};
}
公共组件将接收道具(nextrops:ifactorymethodrops):无效{
this.listItemEntityTypeName=未定义;
//初始化状态
此.state={
键入:“ListItem”,
状态:this.listNotConfigured(this.props)“‘请在Web部件属性中配置列表’:‘就绪’,
详细信息机构状态:{
列:[],
项目:[]
},
详细信息WSListItemState:{
列:[],
项目:[]
},
详细信息目录列表状态:{
列:[],
项目:[]
},
详细信息列表项状态:{
列:[],
项目:[]
},
};
}
public render():React.ReactElement{
让{type,
地位
详细信息机构状态,
详细信息WSListItemState,
详细信息目录列表状态,
DetailsAnounceListItemState}=this.state;
开关(this.props.listName)
{
案例“列表”:
返回(
);         
案例“公告”:
返回(
);
案例“新闻”:
返回(
);
案例“目录”:
返回(
);
违约:
打破
}
}
private readItems():void{
这是我的国家({
状态:“正在加载所有项目…”
});
let factory=新的ListItemFactory();
//在这里,我们实际使用模式来简化编码。
开关(this.props.listName)
{
案例“列表”:
让listItems=factory.getItems(this.props.spHttpClient、this.props.siteUrl、this.props.listName);
这是我的国家({
状态:`已成功加载${listItems.length}项',
详细信息机构状态:{
项目:列表项目,
栏目:[
]
}
});      
打破
案例“公告”:
将announcementlistItems=factory.getItems(this.props.spHttpClient、this.props.siteUrl、this.props.listName)作为IANNounceListItem[];
这是我的国家({
状态:`已成功加载${listItems.length}项',
详细信息列表项状态:{
项目:公告列表项目,
列:[]
}
});          
打破
案例“新闻”:
让newsListItems=factory.getItems(this.props.spHttpClient、this.props.siteUrl、this.props.listName)作为INewsListItem[];
这是我的国家({
状态:`已成功加载${listItems.length}项',
详细信息WSListItemState:{
项目:新闻列表项目,
列:[]
}
});      
打破
案例“目录”:
让directoryListItems=factory.getItems(this.props.spHttpClient、this.props.siteUrl、this.props.listName)作为IDirectoryListItem[];
这是我的国家({
状态:`已成功加载${listItems.length}项',
详细信息目录列表状态:{
项目:目录列表项目,
列:[]
}
});   
布雷
  private readItems() {
    this.setState({
      status: 'Loading all items...'
    });
    let factory = new ListItemFactory();

    //Here its where we actually use the pattern to make our coding easier.
    switch(this.props.listName)
    {
      case "List":
        this.setState({
          status: `Successfully loaded ${listItems.length} items`,
          DetailsListItemState : {
            items: announcementlistItems,
            columns: []
          }
        });          
        break;

        break;
      case "Announcements":
        let announcementlistItems  = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName) as IAnnouncementListItem[];  
        this.setState({
          status: `Successfully loaded ${listItems.length} items`,
          DetailsAnnouncementListItemState : {
            items: announcementlistItems,
            columns: []
          }
        });          
        break;
      case "News":
        let newsListItems  = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName) as INewsListItem[];  
        this.setState({
          status: `Successfully loaded ${listItems.length} items`,
          DetailsNewsListItemState : {
            items: newsListItems,
            columns: []
          }
        });      
        break;
      case "Directory":
        let directoryListItems  = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName) as IDirectoryListItem[];  
        this.setState<keyof {}>({
          status: `Successfully loaded ${listItems.length} items`,
          DetailsDirectoryListItemState : {
            items: directoryListItems,
            columns: []
          }
        });   
        break;
      default : 
        break;
    }    
  }
  setStateWithList() {
    const factory = new ListItemFactory();
    const items  = factory.getItems(this.props.spHttpClient,
    this.props.siteUrl, this.props.listName); 
    const keyPart = this.props.listName === 'Items' ? '' : this.props.listName;    
    this.setState({
        status: `Successfully loaded ${items.length} items`,
        ['Details' + keyPart + 'ListItemState' as keyof IFactoryMethodProps] : {
          items,
          columns: [
          ]
        }
      });      
    }
  private readItems() {
    this.setState({
      status: 'Loading all items...'
    });

    //Here its where we actually use the pattern to make our coding easier.
    if (this.props.listName) {
      this.setStateWithList();
    }   
  }
  private readItems() {
    this.setState({
      status: 'Loading all items...'
    });

    if (this.props.listName) {
      this.setStateWithList();
    }  
  }
  public render() {
    let { type, 
      status, 
      DetailsListItemState, 
      DetailsNewsListItemState, 
      DetailsDirectoryListItemState, 
      DetailsAnnouncementListItemState } = this.state;

        switch(this.props.listName)
        {
          case "List":
            return (
              <div>
                <MarqueeSelection selection={ this._selection }>
                  <DetailsList
                    items={ DetailsListItemState.items }
                    columns={ DetailsListItemState.columns }
                    setKey='set'
                    layoutMode={ DetailsListLayoutMode.fixedColumns }
                    selection={ this._selection }
                    selectionPreservedOnEmptyClick={ true }                
                    compact={ true }
                  />
                </MarqueeSelection>
              </div>
            );         
          case "Announcements":
            return (
              <div>
                <MarqueeSelection selection={ this._selection }>
                  <DetailsList
                    items={ DetailsAnnouncementListItemState.items }
                    columns={ DetailsAnnouncementListItemState.columns }
                    setKey='set'
                    layoutMode={ DetailsListLayoutMode.fixedColumns }
                    selection={ this._selection }
                    selectionPreservedOnEmptyClick={ true }                
                    compact={ true }
                  />
                </MarqueeSelection>
              </div>
            );
        case "News":
          return (
            <div>
              <MarqueeSelection selection={ this._selection }>
                <DetailsList
                  items={ DetailsNewsListItemState.items }
                  columns={ DetailsNewsListItemState.columns }
                  setKey='set'
                  layoutMode={ DetailsListLayoutMode.fixedColumns }
                  selection={ this._selection }
                  selectionPreservedOnEmptyClick={ true }                
                  compact={ true }
                />
              </MarqueeSelection>
            </div>
          );
        case "Directory":
          return (
            <div>
              <MarqueeSelection selection={ this._selection }>
                <DetailsList
                  items={ DetailsDirectoryListItemState.items }
                  columns={ DetailsDirectoryListItemState.columns }
                  setKey='set'
                  layoutMode={ DetailsListLayoutMode.fixedColumns }
                  selection={ this._selection }
                  selectionPreservedOnEmptyClick={ true }                
                  compact={ true }
                />
              </MarqueeSelection>
            </div>
          );
        default : 
          break;
      }
    }     
  ListMarqueeSelection(itemState: {fixedColumns: number, colums: IColumn[], items: IListItem[] }) => (
       <div>
         <MarqueeSelection selection={ this._selection }>
           <DetailsList
             items={ itemState.items }
             columns={ itemState.columns }
             setKey='set'
             layoutMode={ DetailsListLayoutMode.fixedColumns }
             selection={ this._selection }
             selectionPreservedOnEmptyClick={ true }                
             compact={ true }>
           </DetailsList
         </MarqueeSelection>
     </div>
    );  
  render() {
    switch(this.props.listName)
    {
        case "List":
          return <this.ListMarqueeSelection
            itemState={this.state.DetailsListItemState}/>;
        case "News":
          return <this.ListMarqueeSelection
            itemState={this.state.DetailsNewsListItemState}/>;
        case "Announcements":
          return (<this.ListMarqueeSelection
            itemState={this.state.DetailsAnnouncementsListItemState}/>;
        case "Directory":
          return <this.ListMarqueeSelection
            itemState={this.state.DetailsDirectoryListItemState}/>;
        default:
          return undefined;
    }
  }
export default class FactoryMethod extends React.Component<any, IFactoryMethodState> {
  listItemEntityTypeName?: string;
  _selection: Selection;

  constructor(props: IFactoryMethodProps, state: any) {
    super(props);
    setInitialState();
  }

  componentWillReceiveProps(nextProps: IFactoryMethodProps) {
    this.listItemEntityTypeName = undefined;
    setInitialState();
  }    


  render() {
    switch(this.props.listName)
    {
        case "List":
          return <this.ListMarqueeSelection
            itemState={this.state.DetailsListItemState}/>;
        case "News":
          return <this.ListMarqueeSelection
            itemState={this.state.DetailsNewsListItemState}/>;
        case "Announcements":
          return (<this.ListMarqueeSelection
            itemState={this.state.DetailsAnnouncementsListItemState}/>;
        case "Directory":
          return <this.ListMarqueeSelection
            itemState={this.state.DetailsDirectoryListItemState}/>;
        default:
          return undefined;
    }
  }

  readItems() {
    this.setState({
      status: 'Loading all items...'
    });


    if (this.props.listName) {
        this.setStateWithList();
    }    
  }

  setInitialState() {
    this.state = {
      type: 'ListItem',
      status: this.listNotConfigured(this.props)
        ? 'Please configure list in Web Part properties'
        : 'Ready',
      DetailsListItemState:{
        columns:[],
        items:[]
      },
      DetailsNewsListItemState:{
        columns:[],
        items:[]
      },
      DetailsDirectoryListItemState:{
        columns:[],
        items:[]
      },
      DetailsAnnouncementListItemState:{
        columns:[],
        items:[]
      },
    };
  }

  ListMarqueeSelection = (itemState: {fixedColumns: number, colums: {}[], items: {}[] }) => (
   <div>
     <MarqueeSelection selection={ this._selection }>
       <DetailsList
         items={ itemState.items }
         columns={ itemState.columns }
         setKey='set'
         layoutMode={ DetailsListLayoutMode.fixedColumns }
         selection={ this._selection }
         selectionPreservedOnEmptyClick={ true }                
         compact={ true }>
       </DetailsList
     </MarqueeSelection>
   </div>
  );

  setStateWithList() {
    const factory = new ListItemFactory();
    const items  = factory.getItems(this.props.spHttpClient,
    this.props.siteUrl, this.props.listName);  
    const keyPart = this.props.listName === 'Items' ? '' : this.props.listName;    

    // the explicit specification of the type argument `keyof {}` is bad and
    // it should not be required.
    this.setState<keyof {}>({
        status: `Successfully loaded ${items.length} items`,
        ['Details' + keyPart + 'ListItemState'] : {
          items,
          columns: [
          ]
        }
      });      
  }

  _getSelectionDetails() {
    const selectionCount = this._selection.getSelectedCount();

    switch (selectionCount) {
      case 0:
        return 'No items selected';
      case 1:
        return `1 item selected: ${this._selection.getSelection()[0]).name}`;
      default:
        return `${selectionCount} items selected`;
    }
  }

  listNotConfigured(props: IFactoryMethodProps) {
    return !props.listNane || props.listName.length === 0;
  }
}