问题:
我似乎无法更改输入标签(在<Details />
内部)中的占位符。
预期行为:
将使用组件的状态及其handleChange
函数来更新输入标签。
实际行为:(很抱歉,正在处理中!)
对输入字段所做的更改仅注册一个字符。
示例::选择FileName
中的所有字符并将其删除显示为console.log()
函数中的handleChange
中已删除的字符。但是,该字段永远不会在视图上更改,而是具有相同的值。
我尝试过的事情:
我尝试使用props
和state
处理更改,但是没有任何效果。我猜想我可能像我对FileItem
所做的那样,将更改提升到祖先,但是我不确定。
实际代码:
import * as React from "react";
import { IFileModel, IFileWrapper } from "../models/fileModel";
import { Fortress } from "../../dependencies/fortress";
let divStyle = {
width: "50px",
border: "1px solid #000",
padding: "5px",
margin: "5px"
};
declare let config : {[key : string] : string};
const $F = new Fortress(config);
export class DetailsPanel extends React.Component<IFileModel, any> {
constructor(props : IFileModel) {
super(props);
this.state = {
isDisplayed : false
};
this.toggle = this.toggle.bind(this);
}
toggle() {
let newIsCollapsed = !(this.state.isDisplayed);
this.setState({ isDisplayed : newIsCollapsed })
}
render() {
return(
<div>
<div>
<input className="button" type="submit" value={ (!this.state.isDisplayed) ? "Show Panel" : "Hide Panel" } onClick={this.toggle} />
</div>
{ this.state.isDisplayed ? <Details {...this.props} /> : null }
</div>
);
}
}
export class Details extends React.Component <IFileModel, any> {
constructor(props : IFileModel) {
super(props);
this.state = {
currentFile : this.props
};
this.onSubmit = this.onSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
// http://localhost/admin/shared/file/SaveFile/?
/*
FileId: 1
FileName: shirt.pdf
LCID: 2057
FileVariation: 0
DisplayName: shirt.png
OriginalFileName: shirt__1_3_2057.pdf
CategoryId: 0
FileType: 1
FileExtension: png
FileSize: 419920
Width: 615
Height: 462
FileData:
AllowedVariantTypes: 0
RequireAuthorization: 0
AdminId: 1
CreationDate: /Date(1450692426023)/
ModifyDate: /Date(1450692426023)/
ExpiryDate: /Date(253402300799997)/
*/
handleChange(e : any) {
console.log(e.target.name, e.target.value);
this.setState({ [e.target.name] : e.target.value });
}
onSubmit() {
const state = this.state.currentFile;
console.log($F.writeAdminUrl("shared", "file", "SaveFile"));
console.log(JSON.stringify(state));
// fetch($F.writeAdminUrl("shared", "file", "SaveFile"), {
// method: "POST",
// headers: {
// "credentials": "same-origin",
// "mode": "no-cors",
// "Content-Type" : "application/json"
// },
// body : JSON.stringify({ fileId : state.fileId })
// })
}
render() {
const currentFile = this.props;
return(
<div style={{border: "1px dashed black", padding: "4px"}}>
<div>
<p> File Name: </p>
<input type="text" value={currentFile.fileName} name="fileName" onChange={this.handleChange} />
</div>
<div>
<p> Image: </p>
<input type="text" value={currentFile.imageUrl} name="imageUrl" onChange={this.handleChange} />
</div>
<div>
<p> Creation date: </p>
<input type="text" value={currentFile.creationDate} name="creationDate" onChange={this.handleChange} />
</div>
<div>
<p> LCID: </p>
<input type="text" name="LCID" value={currentFile.LCID} onChange={this.handleChange} />
</div>
<div>
<input onClick={(currentFile) ? this.onSubmit : null} type="submit"/>
</div>
</div>
);
}
}
export class FileItem extends React.Component<IFileModel> {
constructor(props : IFileModel) {
super(props);
this.onSelect = this.onSelect.bind(this);
}
onSelect() {
this.props.onSelect(this.props);
}
render() {
return (
<div className="fileItem" style={{ width: "100px", height: '150px', float: 'left' }} onClick={this.onSelect}>
<img src={"http://localhost/content/image/" + this.props.imageUrl} style={divStyle} />
{this.props.fileName}
<button className="edit" />
</div>
);
}
}
export class FileList extends React.Component<any, any> {
constructor(props : any) {
super(props);
this.state = { files: [], skip: 0, take: 10 }
this.increaseTake = this.increaseTake.bind(this);
this.onSelect = this.onSelect.bind(this);
}
getImages(skip : number, take : number, shouldAdd : boolean) {
var that = this;
fetch("http://localhost/admin/shared/file/GetImages?take=" + take + "&skip=" + skip + "&FileType=0&_2331223a3543as", {
credentials: "same-origin", mode: "no-cors"
})
.then(function(response) {
return response.json();
})
.then(function (results) {
var newFiles = results.data.map((file : any) => ({
imageUrl: file.OriginalFileName,
fileName: file.DisplayName,
fileId: file.FileId,
creationDate: file.CreationDate,
LCID: file.LCID
}));
if (shouldAdd) {
newFiles = that.state.files.concat(newFiles);
}
that.setState({ files: newFiles });
});
}
onSelect(file : IFileModel) {
this.props.onFileSelected(file);
}
increaseTake() {
var currentSkip = this.state.skip + 10;
this.setState({ skip: currentSkip });
this.getImages(currentSkip, this.state.take, true);
}
componentWillMount() {
// perfom ajax call
this.getImages(0, this.state.take, true);
}
render() {
return (<div>
{this.state.files.map((item: IFileModel, index: number) =>
<FileItem key={index} {...item} onSelect={this.onSelect} />
)
}
<div style={{ clear: 'both' }}></div>
<div onClick={this.increaseTake}>take more</div>
</div>)
}
}
export class FileGallery extends React.Component <any, any> {
constructor(props : any) {
super(props);
let fm : IFileModel;
this.state = {
sidebarCollapsed : false,
selectedFile : fm
};
this.onFileSelected = this.onFileSelected.bind(this);
}
onFileSelected(file : IFileModel) {
this.setState({ selectedFile : file });
}
render() {
const selectedFile = this.state.selectedFile;
return (
<div>
<div className="FileGalleryHeader">
<div>Galley</div>
<div>Upload</div>
</div>
<div className="FileGalleyMain" style={{ width: "80%", display : 'block', height:"400px", overflow : "auto", float : "left"}}>
<FileList onFileSelected={this.onFileSelected}/>
</div>
<div style={{ width: "20%", display: "block", float : "right", height: "800px"}}>
<DetailsPanel {...selectedFile} onSubmit={(selectedFile) ? selectedFile.onSubmit : null } />
</div>
</div>);
}
}
型号:
export interface IFileModel {
fileId: number;
fileName: string;
categoryId: number;
fileType: number;
fileExtension: string;
fileSize: string;
width: number;
height: number;
creationDate: string;
imageUrl: string;
LCID: string;
onSubmit: Function;
onSelect: Function;
}
export interface IFileWrapper {
file: IFileModel;
}
答案 0 :(得分:0)
就我所查看的代码而言,它可能有两个问题:
Details
handleChange(e : any) {
console.log(e.target.name, e.target.value);
this.setState({ [e.target.name] : e.target.value });
}
这应该是:
handleChange(e : any) {
console.log(e.target.name, e.target.value);
this.setState({ currentFile: {
...this.state.currentFile,
[e.target.name]: e.target.value
});
}
props
设置为input
的值,而应将其设置为state
const currentFile = this.props;
return(
<div style={{border: "1px dashed black", padding: "4px"}}>
<div>
<p> File Name: </p>
<input type="text" value={currentFile.fileName} name="fileName" onChange={this.handleChange} />
</div>
这应该是:
const currentFile = this.state;
return(
<div style={{border: "1px dashed black", padding: "4px"}}>
<div>
<p> File Name: </p>
<input type="text" value={currentFile.fileName} name="fileName" onChange={this.handleChange} />
</div>