Erstellen, Aktualisieren und Löschen von Dateien in einem Container
In dieser Übung aktualisieren Sie das vorhandene Projekt, um Dateien in einem SharePoint Embedded-Container zu speichern.
Hinzufügen von Microsoft Graph-Typdeklarationen zum Projekt
Bevor wir die neuen React-Komponenten erstellen, beginnen wir mit dem Aktualisieren des Projekts.
In dieser Übung verwenden wir typen, die von Microsoft Graph bereitgestellt werden. Da wir das npm-Paket, das sie enthält, nicht installiert haben, müssen wir dies zuerst tun.
Führen Sie in der Befehlszeile den folgenden Befehl im Stammordner für unser Projekt aus:
npm install @microsoft/microsoft-graph-types -DE
Aktualisieren der React Containers-Komponente zum Anzeigen von Dateien
Erinnern Sie sich an die vorherige Übung, dass wir einen Platzhalter in unserer Containerkomponente gelassen haben, der verwendet wird, um den Inhalt des ausgewählten Containers anzuzeigen.
Wir haben unsere Files
Komponente nicht erstellt, aber beginnen wir damit, die Containers
Komponente zu aktualisieren, um den Platzhalter durch die Komponente zu ersetzen, die Files
wir erstellen.
Suchen Und öffnen Sie die Datei ./src/components/containers.tsx .
Fügen Sie die folgende Import-Anweisung zur Liste der vorhandenen Importe am Anfang der Datei hinzu:
import { Files } from "./files";
Suchen Sie als Nächstes den folgenden Platzhaltercode am Ende der Datei...
{selectedContainer && (`[[TOOD]] container "${selectedContainer.displayName}" contents go here`)}
… und ersetzen Sie sie durch den folgenden Code:
{selectedContainer && (<Files container={selectedContainer} />)}
Erstellen der React-Komponente "Dateien"
Beginnen wir damit, eine neue React-Komponente zu erstellen, um den Inhalt der Container anzuzeigen und zu verwalten.
Erstellen Sie die neue Datei ./src/components/files.tsx, und fügen Sie den folgenden Code hinzu. Dies ist die Bausteinekomponente, die alle Importe und das Gerüst unseres Bauteils umfasst:
import React, {
useState,
useEffect,
useRef
} from 'react';
import { Providers } from "@microsoft/mgt-element";
import {
AddRegular, ArrowUploadRegular,
FolderRegular, DocumentRegular,
SaveRegular, DeleteRegular,
} from '@fluentui/react-icons';
import {
Button, Link, Label, Spinner,
Input, InputProps, InputOnChangeData,
Dialog, DialogActions, DialogContent, DialogBody, DialogSurface, DialogTitle, DialogTrigger,
DataGrid, DataGridProps,
DataGridHeader, DataGridHeaderCell,
DataGridBody, DataGridRow,
DataGridCell,
TableColumnDefinition, createTableColumn,
TableRowId,
TableCellLayout,
OnSelectionChangeData,
SelectionItemId,
Toolbar, ToolbarButton,
makeStyles
} from "@fluentui/react-components";
import {
DriveItem
} from "@microsoft/microsoft-graph-types-beta";
import { IContainer } from "./../common/IContainer";
require('isomorphic-fetch');
interface IFilesProps {
container: IContainer;
}
interface IDriveItemExtended extends DriveItem {
isFolder: boolean;
modifiedByName: string;
iconElement: JSX.Element;
downloadUrl: string;
}
export const Files = (props: IFilesProps) => {
// BOOKMARK 1 - constants & hooks
// BOOKMARK 2 - handlers go here
// BOOKMARK 3 - component rendering return (
return
(
<div>
</div>
);
}
export default Files;
Hinweis
Beachten Sie die // BOOKMARK #
Kommentare in der Komponente. Diese stellen sicher, dass Sie Code an den richtigen Stellen hinzufügen.
Anzeigen einer Liste der ausgewählten Containerinhalte
Zunächst müssen wir den Inhalt des ausgewählten Containers anzeigen. Dazu verwenden wir die DataGrid
Komponente aus der React-Bibliothek der Fluent-Benutzeroberfläche.
Fügen Sie das folgende Markup innerhalb des <div>
-Elements in der return()
-Anweisung nach dem // BOOKMARK 3
Kommentar hinzu:
<DataGrid
items={driveItems}
columns={columns}
getRowId={(item) => item.id}
resizableColumns
columnSizingOptions={columnSizingOptions}
>
<DataGridHeader>
<DataGridRow>
{({ renderHeaderCell }) => (
<DataGridHeaderCell>{renderHeaderCell()}</DataGridHeaderCell>
)}
</DataGridRow>
</DataGridHeader>
<DataGridBody<IDriveItemExtended>>
{({ item, rowId }) => (
<DataGridRow<IDriveItemExtended> key={rowId}>
{({ renderCell, columnId }) => (
<DataGridCell>
{renderCell(item)}
</DataGridCell>
)}
</DataGridRow>
)}
</DataGridBody>
</DataGrid>
Enthält DataGrid
einige Verweise auf Auflistungen, Einstellungen und Methoden, die wir einrichten müssen. Beginnen wir mit den visuellen Elementen, und dann erhalten wir die Daten.
Die Größe der DataGrid
Spalten im kann entsprechend den von uns festgelegten Eigenschaften geändert werden. Erstellen Sie eine neue Konstante, columnSizingOptions
, und fügen Sie den Code unmittelbar vor dem // BOOKMARK 3
Kommentar hinzu:
const columnSizingOptions = {
driveItemName: {
minWidth: 150,
defaultWidth: 250,
idealWidth: 200
},
lastModifiedTimestamp: {
minWidth: 150,
defaultWidth: 150
},
lastModifiedBy: {
minWidth: 150,
defaultWidth: 150
},
actions: {
minWidth: 250,
defaultWidth: 250
}
};
Definieren Sie als Nächstes die Struktur- und Renderingeinstellungen für alle Spalten in DataGrid
. Erstellen Sie dazu eine neue Sammlung , columns
und fügen Sie sie unmittelbar vor der erstellung hinzu columnSizingOptions
:
const columns: TableColumnDefinition<IDriveItemExtended>[] = [
createTableColumn({
columnId: 'driveItemName',
renderHeaderCell: () => {
return 'Name'
},
renderCell: (driveItem) => {
return (
<TableCellLayout media={driveItem.iconElement}>
<Link href={driveItem!.webUrl!} target='_blank'>{driveItem.name}</Link>
</TableCellLayout>
)
}
}),
createTableColumn({
columnId: 'lastModifiedTimestamp',
renderHeaderCell: () => {
return 'Last Modified'
},
renderCell: (driveItem) => {
return (
<TableCellLayout>
{driveItem.lastModifiedDateTime}
</TableCellLayout>
)
}
}),
createTableColumn({
columnId: 'lastModifiedBy',
renderHeaderCell: () => {
return 'Last Modified By'
},
renderCell: (driveItem) => {
return (
<TableCellLayout>
{driveItem.modifiedByName}
</TableCellLayout>
)
}
}),
createTableColumn({
columnId: 'actions',
renderHeaderCell: () => {
return 'Actions'
},
renderCell: (driveItem) => {
return (
<>
<Button aria-label="Download"
disabled={!selectedRows.has(driveItem.id as string)}
icon={<SaveRegular />}>Download</Button>
<Button aria-label="Delete"
icon={<DeleteRegular />}>Delete</Button>
</>
)
}
}),
];
Dieser Code verwendet die Hilfsmethode createTableColumn()
, um jeder Spalte eine ID zu geben und anzugeben, wie die Header- und Textzellen in der Tabelle gerendert werden.
Fügen Sie bei der DataGrid
Konfiguration die folgenden Konstanten hinzu, um den Zustand der React-App mit den Eigenschaften zu verwalten, die unser vorhandener Code verwendet. Fügen Sie den folgenden Code unmittelbar vor dem // BOOKMARK 1
-Kommentar ein:
const [driveItems, setDriveItems] = useState<IDriveItemExtended[]>([]);
const [selectedRows, setSelectedRows] = useState<Set<SelectionItemId>>(new Set<TableRowId>([1]));
Nun fügen wir einige Handler hinzu, um die Daten aus unserem Container abzurufen und anzuzeigen.
Fügen Sie den folgenden Handler und React-Hook hinzu, um den Inhalt des ausgewählten Containers abzurufen. Der useEffect
Hook wird ausgeführt, wenn die Komponente zum ersten Mal gerendert wird, sowie wenn sich die Eingabeeigenschaften der <Files />
Komponente ändern.
Fügen Sie den folgenden Code unmittelbar vor dem // BOOKMARK 2
-Kommentar ein:
useEffect(() => {
(async () => {
loadItems();
})();
}, [props]);
const loadItems = async (itemId?: string) => {
try {
const graphClient = Providers.globalProvider.graph.client;
const driveId = props.container.id;
const driveItemId = itemId || 'root';
// get Container items at current level
const graphResponse = await graphClient.api(`/drives/${driveId}/items/${driveItemId}/children`).get();
const containerItems: DriveItem[] = graphResponse.value as DriveItem[]
const items: IDriveItemExtended[] = [];
containerItems.forEach((driveItem: DriveItem) => {
items.push({
...driveItem,
isFolder: (driveItem.folder) ? true : false,
modifiedByName: (driveItem.lastModifiedBy?.user?.displayName) ? driveItem.lastModifiedBy!.user!.displayName : 'unknown',
iconElement: (driveItem.folder) ? <FolderRegular /> : <DocumentRegular />,
downloadUrl: (driveItem as any)['@microsoft.graph.downloadUrl']
});
});
setDriveItems(items);
} catch (error: any) {
console.error(`Failed to load items: ${error.message}`);
}
};
Die loadItems
Funktion verwendet den Microsoft Graph-Client, um eine Liste aller Dateien innerhalb des aktuellen Ordners abzurufen, wobei standardmäßig der root
verwendet wird, wenn kein Ordner bereits ausgewählt ist.
Anschließend wird die von Microsoft Graph zurückgegebene Auflistung von DriveItems
verwendet und einige weitere Eigenschaften hinzugefügt, um den Code später zu vereinfachen. Am Ende der -Methode wird die setDriveitems()
Zustandsaccessormethode aufgerufen, die ein erneutes Rendern der Komponente auslöst. Die driveItems
werden für die DataGrid.items
-Eigenschaft festgelegt, die erklärt, warum die Tabelle einige Informationen anzeigt.
Testen des Renderns des Auflistens des Inhalts eines Containers
Testen Sie nun die clientseitige React-App, um sicherzustellen, dass die <Files />
Komponente den Inhalt des ausgewählten Containers anzeigt.
Führen Sie über die Befehlszeile im Stammordner des Projekts den folgenden Befehl aus:
npm run start
Wenn der Browser geladen wird, melden Sie sich mit demselben Geschäfts-, Schul- und Unikonto an, das Sie verwendet haben.
Wählen Sie nach der Anmeldung einen vorhandenen Container aus. Wenn dieser Container bereits Inhalte enthält, wird er wie folgt angezeigt:
Wenn Sie die Datei auswählen, in diesem Fall ein Word-Dokument, wird eine neue Registerkarte geöffnet, und die URL des Elements wird geladen. In diesem Beispiel wird die Datei in Word Online geöffnet.
Unterstützung für das Herunterladen von Dateien hinzufügen
Nachdem die Inhaltsanzeigefunktion abgeschlossen ist, aktualisieren wir die Komponente, um das Herunterladen von Dateien zu unterstützen.
Fügen Sie zunächst den folgenden Code unmittelbar vor dem // BOOKMARK 1
Kommentar hinzu:
const downloadLinkRef = useRef<HTMLAnchorElement>(null);
Als Nächstes möchten wir sicherstellen, dass ein Element in ausgewählt DataGrid
ist, bevor es heruntergeladen werden kann. Andernfalls wird die Schaltfläche Herunterladen so deaktiviert, wie sie derzeit ist.
DataGrid
Fügen Sie in drei Eigenschaften hinzu, um festzulegen, dass es einen Auswahlmodus für ein einzelnes Element unterstützt (selectionMode
), und verfolgen Sie, welche Elemente ausgewählt werden (selectedItems
) und was zu tun ist, wenn sich die Auswahl ändert (onSelectionChange
).
<DataGrid
...
selectionMode='single'
selectedItems={selectedRows}
onSelectionChange={onSelectionChange}>
Fügen Sie als Nächstes den folgenden Handler unmittelbar vor dem // BOOKMARK 2
Kommentar hinzu:
const onSelectionChange: DataGridProps["onSelectionChange"] = (event: React.MouseEvent | React.KeyboardEvent, data: OnSelectionChangeData): void => {
setSelectedRows(data.selectedItems);
}
Wenn nun ein Element in der Liste ausgewählt ist, sehen Sie, dass die Schaltfläche Herunterladen nicht mehr deaktiviert ist.
Die Downloadoption verwendet einen ausgeblendeten Link, mit dem wir zuerst den Downloadlink für das ausgewählte Element programmgesteuert festlegen und dann programmgesteuert die folgenden Aktionen ausführen:
- Legen Sie die URL des Links auf die Download-URL des Elements fest.
- Wählen Sie den Link aus.
Dadurch wird der Download für den Benutzer ausgelöst.
Fügen Sie das folgende Markup direkt nach dem Öffnen <div>
in der return()
-Methode hinzu:
<a ref={downloadLinkRef} href="" target="_blank" style={{ display: 'none' }} />
Suchen Sie nun die vorhandene columns
Konstante, die Sie zuvor hinzugefügt haben, und suchen Sie die , die createTableColumn
auf verweist columnId: 'actions'
. Fügen Sie in der renderCell
-Eigenschaft einen onClick
Handler hinzu, der aufruft onDownloadItemClick
. Die Schaltfläche sollte wie folgt aussehen, wenn Sie fertig sind:
<Button aria-label="Download"
disabled={!selectedRows.has(driveItem.id as string)}
icon={<SaveRegular />}
onClick={() => onDownloadItemClick(driveItem.downloadUrl)}>Download</Button>
Fügen Sie schließlich den folgenden Handler unmittelbar nach dem vorhandenen onSelectionChange
Ereignishandler hinzu, den Sie zuvor hinzugefügt haben. Dadurch werden die beiden zuvor erwähnten programmgesteuerten Schritte behandelt:
const onDownloadItemClick = (downloadUrl: string) => {
const link = downloadLinkRef.current;
link!.href = downloadUrl;
link!.click();
}
Speichern Sie Ihre Änderungen, aktualisieren Sie den Browser, und wählen Sie den Link Herunterladen aus, um zu sehen, wie die Datei heruntergeladen wird.
Hinzufügen der Möglichkeit zum Erstellen eines Ordners in einem Container
Wir setzen den Aufbau der <Files />
Komponente fort, indem wir Unterstützung für das Erstellen und Anzeigen von Ordnern hinzufügen.
Fügen Sie zunächst den folgenden Code unmittelbar vor dem // BOOKMARK 1
Kommentar hinzu. Dadurch werden die erforderlichen React-Zustandswerte hinzugefügt, die wir verwenden:
const [folderId, setFolderId] = useState<string>('root');
const [folderName, setFolderName] = useState<string>('');
const [creatingFolder, setCreatingFolder] = useState<boolean>(false);
const [newFolderDialogOpen, setNewFolderDialogOpen] = useState(false);
Um einen neuen Ordner zu erstellen, wird dem Benutzer ein Dialogfeld angezeigt, wenn er eine Schaltfläche in der Symbolleiste auswählt.
Fügen Sie in der return()
-Methode unmittelbar vor den <DataGrid>
folgenden Code hinzu, um den Dialog zu implementieren:
<Toolbar>
<ToolbarButton vertical icon={<AddRegular />} onClick={() => setNewFolderDialogOpen(true)}>New Folder</ToolbarButton>
</Toolbar>
<Dialog open={newFolderDialogOpen}>
<DialogSurface>
<DialogBody>
<DialogTitle>Create New Folder</DialogTitle>
<DialogContent className={styles.dialogContent}>
<Label htmlFor={folderName}>Folder name:</Label>
<Input id={folderName} className={styles.dialogInputControl} autoFocus required
value={folderName} onChange={onHandleFolderNameChange}></Input>
{creatingFolder &&
<Spinner size='medium' label='Creating folder...' labelPosition='after' />
}
</DialogContent>
<DialogActions>
<DialogTrigger disableButtonEnhancement>
<Button appearance="secondary" onClick={() => setNewFolderDialogOpen(false)} disabled={creatingFolder}>Cancel</Button>
</DialogTrigger>
<Button appearance="primary"
onClick={onFolderCreateClick}
disabled={creatingFolder || (folderName === '')}>Create Folder</Button>
</DialogActions>
</DialogBody>
</DialogSurface>
</Dialog>
Das Dialogfeld verwendet einige benutzerdefinierte Stile, die wir noch nicht hinzugefügt haben. Fügen Sie zunächst den folgenden Code unmittelbar vor der Deklaration der Files
Komponente hinzu:
const useStyles = makeStyles({
dialogInputControl: {
width: '400px',
},
dialogContent: {
display: 'flex',
flexDirection: 'column',
rowGap: '10px',
marginBottom: '25px'
}
});
Fügen Sie dann den folgenden Code unmittelbar vor der return()
-Methode in unserer -Komponente hinzu:
const styles = useStyles();
Nachdem die Benutzeroberfläche eingerichtet wurde, müssen wir nun einige Handler hinzufügen. Fügen Sie die folgenden Handler unmittelbar vor dem // BOOKMARK 2
Kommentar hinzu. Diese behandeln das Öffnen des Dialogfelds, speichern den Wert des Neuen Ordnernamens und was geschieht, wenn sie die Schaltfläche im Dialogfeld auswählen:
const onFolderCreateClick = async () => {
setCreatingFolder(true);
const currentFolderId = folderId;
const graphClient = Providers.globalProvider.graph.client;
const endpoint = `/drives/${props.container.id}/items/${currentFolderId}/children`;
const data = {
"name": folderName,
"folder": {},
"@microsoft.graph.conflictBehavior": "rename"
};
await graphClient.api(endpoint).post(data);
await loadItems(currentFolderId);
setCreatingFolder(false);
setNewFolderDialogOpen(false);
};
const onHandleFolderNameChange: InputProps["onChange"] = (event: React.ChangeEvent<HTMLInputElement>, data: InputOnChangeData): void => {
setFolderName(data?.value);
};
Speichern Sie Ihre Änderungen, aktualisieren Sie den Browser, und wählen Sie über dem Inhalt des Containers die Schaltfläche Neuer Ordner aus:
Wählen Sie die Schaltfläche Neuer Ordner aus, geben Sie einen Namen ein, und wählen Sie im Dialogfeld die Schaltfläche Ordner erstellen aus.
Wenn der Ordner erstellt wird, wird er in der Inhaltstabelle aufgeführt:
Wir müssen eine weitere Änderung an unserer Komponente vornehmen. Wenn Sie jetzt einen Ordner auswählen, wird die URL auf einer neuen Registerkarte gestartet, ohne dass die App ausgelassen wird. Das ist nicht das, was wir wollen... Soll ein Drilldown in den Ordner ausgeführt werden.
Lassen Sie uns dies beheben, indem Sie die vorhandene columns
Konstante suchen, die Sie zuvor hinzugefügt haben, und die suchen, die createTableColumn
auf verweist columnId: 'driveItemName'
. Ersetzen Sie in der renderCell
-Eigenschaft die vorhandene <Link />
Komponente durch den folgenden Code. Dadurch werden zwei Verknüpfungen generiert, die darauf basieren, ob das aktuelle Element, das gerendert wird, ein Ordner oder eine Datei ist:
{(!driveItem.isFolder)
? <Link href={driveItem!.webUrl!} target='_blank'>{driveItem.name}</Link>
: <Link onClick={() => {
loadItems(driveItem.id);
setFolderId(driveItem.id as string)
}}>{driveItem.name}</Link>
}
Wenn Sie nun einen Ordner auswählen, zeigt die App den Inhalt des Ordners an.
Hinzufügen der Möglichkeit zum Löschen einer Datei oder eines Ordners
Der nächste Schritt besteht darin, die Möglichkeit zum Löschen eines Ordners oder einer Datei aus dem Container hinzuzufügen.
Um dies zu tun, fügen Sie zunächst den folgenden Code zur liste der useState()
vorhandenen Aufrufe vor dem // BOOKMARK 1
Kommentar hinzu.
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
Fügen Sie als Nächstes ein Dialogfeld hinzu, das als Bestätigung fungiert, wenn der Benutzer die Schaltfläche Löschen auswählt. Fügen Sie den folgenden Code direkt nach der vorhandenen <Dialog>
Komponente in der return()
-Methode hinzu:
<Dialog open={deleteDialogOpen} modalType='modal' onOpenChange={() => setSelectedRows(new Set<TableRowId>([0]))}>
<DialogSurface>
<DialogBody>
<DialogTitle>Delete Item</DialogTitle>
<DialogContent>
<p>Are you sure you want to delete this item?</p>
</DialogContent>
<DialogActions>
<DialogTrigger>
<Button
appearance='secondary'
onClick={() => setDeleteDialogOpen(false)}>Cancel</Button>
</DialogTrigger>
<Button
appearance='primary'
onClick={onDeleteItemClick}>Delete</Button>
</DialogActions>
</DialogBody>
</DialogSurface>
</Dialog>
Aktualisieren Sie die Schaltfläche Löschen , um etwas zu tun, wenn sie ausgewählt ist. Suchen Sie die vorhandene columns
Konstante, die Sie zuvor hinzugefügt haben, und suchen Sie die , die createTableColumn
auf verweist columnId: 'actions'
. Fügen Sie in der renderCell
-Eigenschaft einen onClick
Handler hinzu, der aufruft onDeleteDialogOpen
. Die Schaltfläche sollte wie folgt aussehen, wenn Sie fertig sind:
<Button aria-label="Delete"
icon={<DeleteRegular />}
onClick={() => setDeleteDialogOpen(true)}>Delete</Button>
Fügen Sie schließlich den folgenden Code unmittelbar vor dem // BOOKMARK 2
Kommentar hinzu, um das Löschen des aktuell ausgewählten Elements zu behandeln:
const onDeleteItemClick = async () => {
const graphClient = Providers.globalProvider.graph.client;
const endpoint = `/drives/${props.container.id}/items/${selectedRows.entries().next().value[0]}`;
await graphClient.api(endpoint).delete();
await loadItems(folderId || 'root');
setDeleteDialogOpen(false);
}
Speichern Sie Ihre Änderungen, und aktualisieren Sie den Browser. Wählen Sie die Schaltfläche Löschen für einen der vorhandenen Ordner oder Dateien in Ihrer Sammlung aus. Das Bestätigungsdialogfeld wird angezeigt, und wenn Sie die Schaltfläche Löschen im Dialogfeld auswählen, wird die Inhaltstabelle des Containers aktualisiert, um anzuzeigen, dass das Element gelöscht wurde:
Hinzufügen der Möglichkeit zum Hochladen von Dateien in den Container
Der letzte Schritt besteht darin, die Möglichkeit zum Hochladen von Dateien in einen Container oder einen Ordner innerhalb eines Containers hinzuzufügen.
Fügen Sie zunächst den folgenden Code unmittelbar vor dem // BOOKMARK 1
Kommentar hinzu:
const uploadFileRef = useRef<HTMLInputElement>(null);
Als Nächstes wiederholen wir eine ähnliche Technik, indem wir ein ausgeblendetes <Input>
Steuerelement verwenden, um eine Datei hochzuladen. Fügen Sie den folgenden Code unmittelbar nach dem Öffnen <div>
in der -Methode der Komponente return()
hinzu:
<input ref={uploadFileRef} type="file" onChange={onUploadFileSelected} style={{ display: 'none' }} />
Fügen Sie der Symbolleiste eine Schaltfläche hinzu, um das Dateiauswahldialogfeld auszulösen. Fügen Sie dazu den folgenden Code unmittelbar nach der vorhandenen Symbolleistenschaltfläche hinzu, die einen neuen Ordner hinzufügt:
<ToolbarButton vertical icon={<ArrowUploadRegular />} onClick={onUploadFileClick}>Upload File</ToolbarButton>
Fügen Sie schließlich den folgenden Code unmittelbar vor dem // BOOKMARK 2
Kommentar hinzu, um zwei Ereignishandler hinzuzufügen. Der onUploadFileClick
Handler wird ausgelöst, wenn Sie die Symbolleistenschaltfläche Datei hochladen auswählen, und der onUploadFileSelected
Handler wird ausgelöst, wenn der Benutzer eine Datei auswählt:
const onUploadFileClick = () => {
if (uploadFileRef.current) {
uploadFileRef.current.click();
}
};
const onUploadFileSelected = async (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files![0];
const fileReader = new FileReader();
fileReader.readAsArrayBuffer(file);
fileReader.addEventListener('loadend', async (event: any) => {
const graphClient = Providers.globalProvider.graph.client;
const endpoint = `/drives/${props.container.id}/items/${folderId || 'root'}:/${file.name}:/content`;
graphClient.api(endpoint).putStream(fileReader.result)
.then(async (response) => {
await loadItems(folderId || 'root');
})
.catch((error) => {
console.error(`Failed to upload file ${file.name}: ${error.message}`);
});
});
fileReader.addEventListener('error', (event: any) => {
console.error(`Error on reading file: ${event.message}`);
});
};
Testen Sie die Änderungen, indem Sie die Datei speichern, den Browser aktualisieren und die Schaltfläche Datei hochladen auswählen:
Nachdem Sie eine Datei ausgewählt haben, lädt die App die Datei hoch und aktualisiert die Tabelle des Containersinhalts:
Zusammenfassung
In dieser Übung haben Sie das vorhandene Projekt aktualisiert, um Dateien in einem SharePoint Embedded-Container zu speichern und zu verwalten.