我有以下接口:
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 {
public 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;
}
}
}
最后一部分是我不喜欢的部分,我创建了一个switch语句,因为根据选择的列表,返回数组将是不同的类型,IListItem,IAnnouncementListItem,IDirectoryListItem或INewsListItem。
任何使此方法更短的建议&gt;?
第二。我从我的反应组件中这样称呼它:
// read items using factory method pattern and sets state accordingly
private readItemsAndSetStatus(): void {
this.setState({
status: "Loading all items..."
});
const factory: ListItemFactory = new ListItemFactory();
const items: IListItem[] = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName);
const keyPart: string = 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: [
]
}
});
}
但是你可以看到getitems返回一个ListItem数组,这可以改进吗?
答案 0 :(得分:1)
让我们用这个模拟例子来演示一些技巧......
datasource.xpath(
'subsystem:connection-url',
'subsystem' => 'urn:jboss:domain:datasources:1.2')
#⇒ [#<... name="connection-url" namespace=...
您可以使用具有专门签名的方法重载来获取更具体的类型:
class Example {
public getItems(requester: SPHttpClient, siteUrl: string, listName: string): IListItem[] {
return [];
}
}
const example = new Example();
// IListItem[]
const news = example.getItems(null, '', 'News');
// IListItem[]
const announcements = example.getItems(null, '', 'Announcements');
您可以打破课程并选择合适的课程,而不是在您的big switch语句中包含列表代码......
class Example {
public getItems(requester: SPHttpClient, siteUrl: string, listName: 'News'): INewsListItem[];
public getItems(requester: SPHttpClient, siteUrl: string, listName: 'Announcements'): IAnnouncementListItem[];
public getItems(requester: SPHttpClient, siteUrl: string, listName: string): IListItem[];
public getItems(requester: SPHttpClient, siteUrl: string, listName: string): IListItem[] {
return [];
}
}
const example = new Example();
// INewsListItem[]
const news = example.getItems(null, '', 'News');
// IAnnouncementListItem[]
const announcements = example.getItems(null, '', 'Announcements');
然后,您可以将公共代码提取到基类中。代码的每个部分都更小,更易于阅读。还有一些部分,但它们在逻辑上将事物分开。
还有其他一些方法可以实现您的目标,但这些方法将指向您正确的方向。