目前我正在使用 Kendo React Treelist 组件,我有一个我自己无法解决的问题。当我添加一个元素时,我们可以在这里看到它内联。问题是,当我想再次创建一个时,在我添加一个之后,实体都进入编辑模式。有/有过类似的问题或有想法吗? 添加元素
在这里我们可以看到,新的正在渲染,但旧的也在渲染。这不应该是这样。 加倍元素
在这里你可以看到我的代码:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
TreeList, TreeListToolbar, mapTree, extendDataItem,
removeItems, modifySubItems,
TreeListTextEditor, TreeListBooleanEditor
} from '@progress/kendo-react-treelist';
import { AutoComplete, ComboBox, MultiColumnComboBox, DropDownList, MultiSelect, DropDownTree } from '@progress/kendo-react-dropdowns';
import MyCommandCell from './commandCell.jsx';
import employees from './data';
const subItemsField = 'Children';
const expandField = 'expanded';
const editField = 'inEdit';
var valueOfClasses = { id: "2", text: "Company" };
var parentId = null;
var lastClassname = null;
class DropDownForClasses extends React.Component {
constructor() {
super();
}
state = {
nodeClasses: ["1", "2"],
value: { id: "2", text: "Company" }
}
handleChange = (event) => {
valueOfClasses = event.target.value;
lastClassname = event.target.value.text;
this.setState({
value: event.target.value,
lastClassId: event.target.text
});
}
componentDidMount = () => {
fetch('./Api/Nodes/GetAllClassesForKendoDropDown').then(response => {
if (response.ok) {
return response
} else {
throw new Error('Error with fetching data from server');
}
})
.then(response => response.json())
.then(response => JSON.parse(response))
.then(
result => {
if (result.length == 0) {
} else {
this.setState({
nodeClasses: result
});
}
})
.catch(error => this.setState({ error }));
}
render() {
const { dataItem, field } = this.props;
const cellData = dataItem[field];
return (
<td>
<DropDownList textField="text" dataItemKey="id" data={this.state.nodeClasses} value={this.state.value} onChange={this.handleChange} />
</td>
);
}
}
class CustomCellForClasses extends React.Component {
render() {
const { dataItem, field } = this.props;
const cellData = dataItem[field];
return (
<td>
{dataItem.classId == undefined ? <span >{lastClassname}</span> : <span >{dataItem.classId}</span>}
</td>
);
}
}
class KendoTreeview extends React.Component {
state = {
data: employees.slice(),
expanded: [1, 2, 32],
classId: 3,
inEdit: []
}
addChild = (dataItem) => {
const newRecord = this.createNewItem();
parentId = dataItem.id;
this.setState({
inEdit: [...this.state.inEdit, newRecord],
expanded: [...this.state.expanded, dataItem.id],
data: modifySubItems(
this.state.data,
subItemsField,
item => item.id === dataItem.id,
subItems => [newRecord, ...subItems]
)
});
}
enterEdit = (dataItem) => {
this.setState({
inEdit: [...this.state.inEdit, extendDataItem(dataItem, subItemsField)]
});
}
generateGuid = () => {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
//when pressing add after inline editing
save = (dataItem) => {
var { isNew, inEdit, ...itemToSave } = dataItem;
dataItem.id = this.generateGuid();
dataItem.Class = valueOfClasses.id;
var allCookies = document.cookie.split(';');
for (var i = 0; i < allCookies.length; i++)
document.cookie = allCookies[i] + "=;expires=" + new Date(0).toUTCString();
document.cookie = dataItem.id;
var baseUrl = window.location.origin;
var nameOfEntity = dataItem.name;
fetch(baseUrl + '/Api/Node/CreateNoteFromClient?parentId=' + parentId + "&classId=" + parseInt(valueOfClasses.id) + "&name=" + nameOfEntity + "&id=" + dataItem.id, {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
}
})
.then(response => {
if (response.ok) {
return response
} else {
throw new Error('Error with fetching data from server');
}
})
.then(
this.setState({
data: mapTree(this.state.data, subItemsField, item => item.id === itemToSave.id ? itemToSave : item),
inEdit: this.state.inEdit.filter(i => i.id !== itemToSave.id)
}));
}
cancel = (editedItem) => {
const { inEdit, data } = this.state;
if (editedItem.isNew) {
return this.remove(editedItem);
}
this.setState({
data: mapTree(data, subItemsField,
item => item.id === editedItem.id ? inEdit.find(i => i.id === item.id) : item),
inEdit: inEdit.filter(i => i.id !== editedItem.id)
});
}
remove = (dataItem) => {
this.setState({
data: removeItems(this.state.data, subItemsField, i => i.id === dataItem.id),
inEdit: this.state.inEdit.filter(i => i.id !== dataItem.id)
});
const nodeId = dataItem.id;
if (window.confirm('Are you sure, you want to delete this item?')) {
window.location.href = './Node/Delete/' + nodeId;
}
}
CommandCell = MyCommandCell(this.enterEdit, this.remove, this.save, this.cancel, this.addChild, editField);
onExpandChange = (e) => {
this.setState({
expanded: e.value ?
this.state.expanded.filter(id => id !== e.dataItem.id) :
[...this.state.expanded, e.dataItem.id]
});
}
onItemChange = (event) => {
this.setState({
data: mapTree(
this.state.data,
subItemsField,
item => item.id === event.dataItem.id ?
extendDataItem(item, subItemsField, { [event.field]: event.value }) : item
)
});
}
//When pressing add new and render inline edit setup
addRecord = () => {
const newRecord = this.createNewItem();
this.setState({
data: [newRecord, ...this.state.data],
inEdit: [...this.state.inEdit, { ...newRecord }]
});
}
createNewItem = () => {
const timestamp = new Date().getTime();
return { id: null, isNew: true};
}
componentDidMount = () => {
fetch('./Api/Nodes/GetAllNodesWithChildrenForKendo')
.then(response => {
if (response.ok) {
return response
} else {
throw new Error('Error with fetching data from server');
}
})
.then(response => response.json())
.then(response => JSON.parse(response))
.then(
result => {
if (result.length == 0) {
} else {
this.setState({ data: result.slice()})
}
})
}
render() {
const { data, expanded, inEdit, classId } = this.state;
return (
<TreeList
style={{ overflow: 'auto' }}
data={mapTree(data, subItemsField, item =>
extendDataItem(item, subItemsField, {
[expandField]: expanded.includes(item.id),
[editField]: Boolean(inEdit.find(i => i.id === item.id))
}))
}
editField={editField}
expandField={expandField}
subItemsField={subItemsField}
onItemChange={this.onItemChange}
onExpandChange={this.onExpandChange}
columns={[
{ field: 'name', title: 'Name', width: 280, editCell: TreeListTextEditor, expandable: true },
//{ field: 'Info', title: 'Info', width: 160, editCell: TreeListTextEditor },
{ field: 'classId', title: 'Class', width: 160, cell: CustomCellForClasses, editCell: DropDownForClasses },
{ cell: this.CommandCell, width: 360 }
]}
toolbar={
<TreeListToolbar>
<button
title="Add new"
className="k-button k-primary"
onClick={this.addRecord}
>
Add new
</button>
</TreeListToolbar>
}
/>
);
}
}
ReactDOM.render(
<KendoTreeview />,
document.getElementById('KendoTreeview')
);
命令单元:
import * as React from 'react';
import jquery from 'jquery';
window.$ = window.jQuery = jquery;
export default function MyCommandCell(enterEdit , remove, save, cancel, addChild, editField) {
return class extends React.Component {
EditPerAjax(rowInfo) {
//$(document).ready(function () {
var allCookies = document.cookie.split(';');
for (var i = 0; i < allCookies.length; i++) {
document.cookie = allCookies[i] + "=;expires=" + new Date(0).toUTCString();
}
if (rowInfo.id == null) {
rowInfo.id = document.cookie;
};
$.ajax({
url: '/Node/Edit/' + rowInfo.id,
type: 'GET',
success: function (data) {
$('#titleOfEntity').text('Edit: ' + rowInfo.name);
$('#contentOfBody').html(data);
},
error: function () {
alert("Something went wrong while fetching partial view!");
},
cache: true
});
//});
}
render() {
const { dataItem } = this.props;
return dataItem[editField]
? (
<td>
<div className="modal" role="dialog" id="myModal">
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<h3 id="titleOfEntity" className="modal-title"></h3>
<button type="button" className="close" data-dismiss="modal" aria-label="Close" >
<span aria-hidden="true">×</span>
</button>
</div>
<div id="createNodeFormModalBody" className="modal-body">
<div id="contentOfBody"></div>
</div>
</div>
</div>
</div>
<button
className="k-button"
onClick={() => save(dataItem)}>
{dataItem.isNew
? 'Add'
: 'Update'}
</button>
<button
className="k-button"
onClick={() => cancel(dataItem)}>{dataItem.isNew
? 'Discard'
: 'Cancel'}
</button>
</td>
) : (
<td>
<div className="modal" role="dialog" id="myModal">
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<h3 id="titleOfEntity" className="modal-title"></h3>
<button type="button" className="close" data-dismiss="modal" aria-label="Close" >
<span aria-hidden="true">×</span>
</button>
</div>
<div id="createNodeFormModalBody" className="modal-body">
<div id="contentOfBody"></div>
</div>
</div>
</div>
</div>
<button
className="k-button"
onClick={() => addChild(dataItem)}>
Add Node
</button>
<button className="k-button" id="createModal" data-toggle="modal" data-target="#myModal" data-dismiss="modal" onClick={() => this.EditPerAjax(dataItem)}>Edit</button>
<button
className="k-button"
onClick={() => remove(dataItem)}>
Remove
</button>
</td>
);
}
}
}