![](/img/trans.png)
[英]JS bundled with webpack can resolve to submodules but ts/spfx cannot
[英]Transform a SPFX TS without JS framework to a React TS
我使用 yo @microsoft/sharepoint 創建了一個 webpart 來顯示項目列表。 該解決方案是在沒有 Javascript 框架的情況下創建的。
import { Version } from '@microsoft/sp-core-library';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import {
IPropertyPaneConfiguration,
PropertyPaneTextField
} from '@microsoft/sp-property-pane';
import { escape } from '@microsoft/sp-lodash-subset';
import styles from './GetSpListItemsWebPart.module.scss';
import * as strings from 'GetSpListItemsWebPartStrings';
import {
SPHttpClient,
SPHttpClientResponse
} from '@microsoft/sp-http';
import {
Environment,
EnvironmentType
} from '@microsoft/sp-core-library';
export interface IGetSpListItemsWebPartProps {
description: string;
}
export interface ISPLists {
value: ISPList[];
}
export interface ISPList {
ID:string;
Title: string;
Summary : string;
NewsCategory: string;
Created:string;
AttachmentFiles:{
Name:string;
Url:string;
ServerRelativeUrl: string;
}
}
export default class GetSpListItemsWebPart extends BaseClientSideWebPart<IGetSpListItemsWebPartProps> {
private _getListData(): Promise<ISPLists> {
return this.context.spHttpClient.get(this.context.pageContext.web.absoluteUrl + "/_api/lists/GetByTitle('News')/items?$select=*&$expand=AttachmentFiles",SPHttpClient.configurations.v1)
.then((response: SPHttpClientResponse) => {
return response.json();
});
}
private _renderListAsync(): void {
if (Environment.type == EnvironmentType.SharePoint ||
Environment.type == EnvironmentType.ClassicSharePoint) {
this._getListData()
.then((response) => {
this._renderList(response.value);
});
}
}
public titleurl(query:string){
var path="/Lists/News/DispForm.aspx?ID=";
var currdir=this.context.pageContext.web.absoluteUrl;
var result=currdir+path+query;
return result;
}
private _renderList(items: ISPList[]): void {
let html: string = '<table border=1 width=100% style="border-collapse: collapse;">';
html += '<th>ID</th><th>Title</th> <th>Summary</th><th>Created</th><th>Attachments</th>';
items.forEach((item: ISPList) => {
html += `
<tr>
<td>${item.ID}</td>
<td><a href="${this.titleurl(item.ID)}">${item.Title}</a></td>
<td>${item.Title}</td>
<td>${item.Created}</td>
<td>
<img src="${item.AttachmentFiles[0].ServerRelativeUrl}" width="300px" height="300px" />
</td>
</tr>
`;
});
html += '</table>';
const listContainer: Element = this.domElement.querySelector('#spListContainer');
listContainer.innerHTML = html;
}
public render(): void {
this.domElement.innerHTML = `
<div class="${ styles.getSpListItems }">
<div class="${ styles.container }">
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${ styles.row }">
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
<span class="ms-font-xl ms-fontColor-white">Welcome to SharePoint Modern Developmennt</span>
<p class="ms-font-l ms-fontColor-white">Loading from ${this.context.pageContext.web.title}</p>
<p class="ms-font-l ms-fontColor-white">Retrive Data from SharePoint List</p>
</div>
</div>
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
<div>NEWS List Items</div>
<br>
<div id="spListContainer" />
</div>
</div>`;
this._renderListAsync();
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel
})
]
}
]
}
]
};
}
}
這部分渲染成功。
然后我使用 React 選項創建了一個解決方案 yo @microsoft/sharepoint。 我被困在如何呈現 HTML 文檔上。 以前它用於 this.domElement,但它說它不在類中。 我試圖創建另一個類來呈現似乎不成功。 如何打印結果?
import * as React from 'react';
import styles from './B.module.scss';
import { IBProps } from './IBProps';
import { escape } from '@microsoft/sp-lodash-subset';
import {
SPHttpClient,
SPHttpClientResponse
} from '@microsoft/sp-http';
import {
Environment,
EnvironmentType
} from '@microsoft/sp-core-library';
import * as ReactDOM from 'react-dom';
export interface ISPLists {
value: ISPList[];
}
export interface ISPList {
ID:string;
Title: string;
Summary : string;
NewsCategory: string;
Created:string;
AttachmentFiles:{
Name:string;
Url:string;
ServerRelativeUrl: string;
}
}
export default class B extends React.Component<IBProps, {}> {
public render(): React.ReactElement<IBProps> {
return (
<div className={ styles.b }>
<div id="spListContainer"></div>
<div className={ styles.container }>
<div className={ styles.row }>
<div className={ styles.column }>
<span className={ styles.title }>Welcome to SharePoint!</span>
<p className={ styles.subTitle }>Customize SharePoint experiences using Web Parts.</p>
<p className={ styles.description }>{escape(this.props.description)}</p>
</div>
</div>
</div>
</div>
);
}
}
export class shownews extends B{
constructor(prop){
super(prop);
public _getListData(): Promise<ISPLists> {
return this.context.spHttpClient.get(this.context.pageContext.web.absoluteUrl + "/_api/lists/GetByTitle('News')/items?$select=*&$expand=AttachmentFiles",SPHttpClient.configurations.v1)
.then((response: SPHttpClientResponse) => {
return response.json();
});
}
public _renderListAsync(): void {
if (Environment.type == EnvironmentType.SharePoint ||
Environment.type == EnvironmentType.ClassicSharePoint) {
this._getListData()
.then((response) => {
this._renderList(response.value);
});
}
}
public titleurl(query:string){
var path="/Lists/News/DispForm.aspx?ID=";
var currdir=this.context.pageContext.web.absoluteUrl;
var result=currdir+path+query;
return result;
}
private _renderList(items: ISPList[]): void {
let html: string = '<table border=1 width=100% style="border-collapse: collapse;">';
html += '<th>ID</th><th>Title</th> <th>Summary</th><th>Created</th><th>Attachments</th>';
items.forEach((item: ISPList) => {
html += `
<tr>
<td>${item.ID}</td>
<td><a href="${this.titleurl(item.ID)}">${item.Title}</a></td>
<td>${item.Title}</td>
<td>${item.Created}</td>
<td>
<img src="${item.AttachmentFiles[0].ServerRelativeUrl}" width="300px" height="300px" />
</td>
</tr>
`;
});
html += '</table>';
const listContainer = React.createElement('h1',{},html);
ReactDOM.render(listContainer, document.getElementById('spListContainer'));
this._renderListAsync();
}
}
}
我很抱歉如果有很多關於 SPFX 的教程,關於 CRUD 操作的 REACT JS。 但是,我克隆它,嘗試 npm install 或 npm i -g,沒有一個存儲庫適合我。
2020-01-28
import * as React from 'react';
import styles from './A.module.scss';
import { IAProps } from './IAProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { PageContext } from "@microsoft/sp-page-context";
import { HttpClient, IHttpClientOptions, HttpClientResponse, SPHttpClient, ISPHttpClientOptions, SPHttpClientResponse } from '@microsoft/sp-http';
import {
Environment,
EnvironmentType
} from '@microsoft/sp-core-library';
export interface ISPLists {
value: ISPList[];
};
export interface ISPList {
ID:string;
Title: string;
Summary : string;
NewsCategory: string;
Created:string;
AttachmentFiles:{
Name:string;
Url:string;
ServerRelativeUrl: string;
};
}
export default class A extends React.Component<IAProps, {}> {
public test:any=[];
public data:any=[];
public geturl(query:string){
var path="/Lists/News/DispForm.aspx?ID=";
var currdir=this.props.pagecontext.web.absoluteUrl;
var result=currdir+path+query;
return result;
}
private getListData(){
const opt: ISPHttpClientOptions = { headers: { 'Content-Type': 'application/json;odata=verbose' } };
return this.props.SPHttpClient.get(this.props.pagecontext.web.absoluteUrl + "/_api/lists/GetByTitle('News')/items?$select=*&$expand=AttachmentFiles",SPHttpClient.configurations.v1,opt)
.then((response: SPHttpClientResponse) => {
response.json().then((json: any) => {
for(let i=0;i<json.value.length;i++){
this.data.push(<div><tr>
<td>${json.ID}</td>
<td><a href="${this.geturl(json.ID)}">${json.Title}</a></td>
<td></td>
<td>${json.Created}</td>
<td><img src="${json.AttachmentFiles.ServerRelativeUrl}" width="300px" height="300px" /></td>
</tr></div>);
}
});
});
}
/*
private renderList(item: ISPList[]): void {
item.forEach((item: ISPList) => {
this.data.push(`<tr>
<td>${item.ID}</td>
<td><a href="${this.geturl(item.ID)}">${item.Title}</a></td>
<td></td>
<td>${item.Created}</td>
<td><img src="${item.AttachmentFiles.ServerRelativeUrl}" width="300px" height="300px" /></td>
</tr>`
);
})
console.log(this.data);
};
*/
/*
private push() {
this.test.push(1);
this.test.push(2);
this.test.push(3);
console.log(this.test);
}
*/
public render(): React.ReactElement<IAProps>{
this.getListData();
console.log(this.data);
return (
<div id="splist">
TEST
<table className={styles.container}>
<tr>
<th>ID</th><th>Title</th> <th>Summary</th><th>Created</th><th>Attachments</th>
</tr>
<tr>
<td></td>
<td><a href="${this.titleurl(item.ID)}">TITLE</a></td>
<td></td>
<td>Created</td>
<td>
</td>
</tr>
{this.data}
1234
</table>
</div>
);
}
}
2020-01-28 18:15
this.setState({ items:"<td>{item.ID}</td>
<td>{item.Title}</td>
<td>{item.Summary}</td>
<td>{item.Created}</td>
<td>{item.AttachmentFiles[0].ServerRelativeUrl}</td>" });
這不起作用
this.Title.push(<span><td>{item.Title}</td></span>);
this.Url.push(<span><td>{item.AttachmentFiles[0].ServerRelativeUrl}</td></span>);
這個作品
this.ID.push(item.ID); /* this.Title.push(<span><td>{item.Title}</td></span>); this.Url.push(<span><td>{item.AttachmentFiles[0].ServerRelativeUrl}</td></span>); */ this.forceUpdate();
如果我使用數組並使用 .push 發送包含 HTML 標簽的數據,以下屏幕截圖顯示了問題。
編碼
public renderList(item: ISPList[]): void {
item.forEach((item: ISPList) => {
this.data.push(<tr>);
this.data.push(<td>{item.ID}</td>);
this.data.push(<td>{item.Title}</td>);
this.data.push(<td>{item.AttachmentFiles[0].ServerRelativeUrl}</td>);
this.data.push(</tr>);
//some brackets...
2020-01-28 1956 問題 TR WITHIN TR 問題:如果我將 HTML 標簽和數據寫在一行中,標簽將自行生成。 但是在render方法中,我需要添加一個標簽來包裝它會使我的輸出格式不正確。
//some codes before to get the JSON data
this.data.push(<tr>
<td>{item.ID}</td>
<td>{item.Title}</td>
<td>{item.AttachmentFiles[0].ServerRelativeUrl}</td></tr>);
//some more codes
public render(): React.ReactElement<IAProps>{
return (
<div id="splist">
TEST
<table className={styles.container}>
<tr>
<th>ID</th>
<th>Title</th>
<th>Attachments</th>
</tr>
{this.data}
</table>
</div>
);
}
首先,您需要根據要渲染的組件(具有道具或狀態)來考慮您的解決方案。 在您的解決方案的上下文中,您可以創建一個組件,例如:“GetandRenderListItems.tsx”並執行所有“_getListData()”操作。 每次掛載組件后,您都可以使用 'componentDidMount()' 生命周期鈎子來調用 _getListData() 函數。 然后你需要編寫 html 模板來呈現檢索到的數據(你在 '_renderList()' 方法中所做的所有事情)看看下面的代碼片段以獲得一個想法:
public render(): React.ReactElement<IyourcomponentsProps> {
return (
// your dynamic table html and you should not use inline style but define styles in
scss file and use them.
);
}
然后在你的 'yourwebpart.ts' 文件中,你可以在 render() 方法中渲染這個組件:
public render(): void {
const element: React.ReactElement<IyourwebpartProps > = React.createElement(
GetandRenderListItems,
{
description: this.properties.description,
// similarly assign values to other props
}
);
ReactDom.render(element, this.domElement);
}
希望這會有所幫助。
編輯
您可以使用array.map()例如要使用您的數組呈現表格,您可以編寫類似的內容。
public render () : React.ReactElement<IyourcomponentsProps> {
return(
<div className={styles.someStyle} >
<table className={styles.container}>
<tr>
<th>ID</th><th>Title</th> <th>Summary</th><th>Created</th
<th>Attachments</th>
</tr>
{ yourArray.map(function(item,key){
let url = this.titleurl(item.ID);
return (<tr className={styles.rowStyle} key={key}> //you can use key if you want to track index
<td></td> <td className={styles.someclass}><a href={url}>{item.Title}</a></td>
</tr> );
})}
</table>
</div>
);
}
我使用 .bind .map 函數來實現它。 為項目添加狀態應該是下一個更新。 我在處理數組和打印時遇到困難
整個組件 .tsx 文件
import * as React from 'react';
import styles from './A.module.scss';
import { IAProps } from './IAProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { PageContext } from "@microsoft/sp-page-context";
import { HttpClient, IHttpClientOptions, HttpClientResponse, SPHttpClient, ISPHttpClientOptions, SPHttpClientResponse } from '@microsoft/sp-http';
import {
Environment,
EnvironmentType
} from '@microsoft/sp-core-library';
export interface ISPLists {
value: ISPList[];
};
export interface Istate {
ID:string;
Title: string;
isLoad?: boolean;
Url:string;
AttachmentFiles:{
Name:string;
Url:string;
ServerRelativeUrl: string;
};
}
export interface ISPList {
ID:string;
Title: string;
Summary : string;
NewsCategory: string;
Created:string;
AttachmentFiles:{
Name:string,
Url:string,
ServerRelativeUrl: string,
};
}
/*
MAIN STARTS HERE
2020-01-28
*/
export default class A extends React.Component<IAProps> {
constructor(props){
super(props);
this.loadNews();
this.getListData=this.getListData.bind(this);
this.geturl=this.geturl.bind(this);
this.loadNews=this.loadNews.bind(this);
}
//variables to render html tags
private ID:any = [];
private Title:any = [];
private Url:any = [];
private data:any =[];
private tro:any=[]; //<tr>
private trc:any=[]; //</tr>
private tdo:any=[]; //<td>
private tdc:any=[]; //</td>
private loadNews(){
this.getListData();
/*
this.getListData().then((response) => {
this.renderList(response.value);
});
*/ // when getlist and redner list are different functions
}
public geturl(query:string){
var path="/Lists/News/DispForm.aspx?ID=";
var currdir=this.props.pagecontext.web.absoluteUrl;
var result=currdir+path+query;
return result;
}
private tags(flag:boolean,first:boolean){
// if first data add <tr>
//if last data add </tr>
//
if (flag && first){
document.getElementById("tro").innerHTML = <tr>;
}else if (flag && !first){
document.getElementById("trc").innerHTML = </tr>;
}
}
private getListData() {
const opt: ISPHttpClientOptions = { headers: { 'Content-Type': 'application/json;odata=verbose' } };
this.props.SPHttpClient.get(this.props.pagecontext.web.absoluteUrl + "/_api/web/lists/getbytitle('News')/items?$select=*,AttachmentFiles&$expand=AttachmentFiles/Title&$orderby=ID desc", SPHttpClient.configurations.v1, opt).then((response: SPHttpClientResponse) => {
response.json().then((json: any) => {
for(let i=0;i<json.value.length;i++){
var url=this.geturl(json.value[i].ID);
if(i==0){ // add tags <tr> </tr>
let flag=true; let first=true;
this.tags(flag,first);
}else if(i==json.value.length){
let flag=false; let first=false;
this.tags(flag,first);
}
this.data.push({ID:<td>{json.value[i].ID}</td>,
Title:<td><a href={url} target="_blank">{json.value[i].Title}</a></td>,
Url:<td><img src={json.value[i].AttachmentFiles[0].ServerRelativeUrl} width="300px" height="300px" /></td>
});
// debugger;
this.ID.push(json.value[i].ID);
// this.Title.push(json.value[i].Title);
//this.Url.push(json.value[i].AttachmentFiles[0].absoluteUrl);
this.forceUpdate();
}//close for
});// close response.json
});//close private getListData method
}
// json.value[i].Title}
//json.value[i].AttachmentFiles[0].absoluteUrl}
/*
<td><a href="${this.geturl(json.ID)}">${json.value[i].Title}</a></td>
<td></td>
<td>${json.value[i].Created}</td>
<td><img src="${json.AttachmentFiles.ServerRelativeUrl}" width="300px" height="300px" /></td>
*/
public render(): React.ReactElement<IAProps>{
console.log(this.data);
return (
<div className={styles.a} >
<div className={styles.container} ></div>
<span className={ styles.title }>News</span>
<div className={styles.Table}>
<div className={styles.Heading}>
<table >
<tr>
<div className={styles.Cell}>Title</div>
<div className={styles.Cell}>Created</div>
<div className={styles.Cell}>IMGSRC</div>
</tr>
<div className={styles.Cell}>
<span id="tro"></span>
{this.data.map((data)=>
<div> {data.ID}</div>
)
}
</div>
<div className={styles.Cell}>
{this.data.map((data)=>
<div> {data.Title}</div>
)
}
</div>
<div className={styles.Cell}>
{this.data.map((data)=>
<div> {data.Url}</div>
)
}
<span id="trc"></span>
</div>
</table>
</div>
</div>
</div>
);
}
}
在渲染方法中.map函數如下
<div className={styles.Cell}>
{this.data.map((data)=>
<div> {data.Url}</div>
)
}
<span id="trc"></span>
</div>
要訪問數組中的數據對象,必須在定義類后在構造函數中聲明.bind 。
export default class A extends React.Component<IAProps> {
constructor(props){
super(props);
this.loadNews();
this.getListData=this.getListData.bind(this);
this.geturl=this.geturl.bind(this);
this.loadNews=this.loadNews.bind(this);
}
//variables to render html tags
private data:any =[];
中途。 這是原型。 一旦我能夠提取數據,我就可以設置 CSS 樣式
感謝您的幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.