Я новичок в ReactJ и мне нужна помощь. У меня есть 4 Combobox, и они должны взаимодействовать друг с другом. Итак, на первом уровне у меня есть бизнес-группа, второе бизнес-подразделение, третье - поставщик, а четвертое - менеджер по продукту.
Если я выбираю запись в бизнес-группе, параметры в выпадающих списках (единица, продавец, менеджер) должны быть обновлены. Но также, если я выберу поставщика (третий уровень), в комбинированных списках бизнес-группы, подразделения и менеджера по продукции должны быть только опции для выбранного поставщика.
У меня есть массив, когда app.tsx будет монтироваться. Я разделил этот массив для бизнес-группы и заполнил все выпадающие списки. Это правильный путь для расщепления? И как комбо-боксы могут взаимодействовать друг с другом. Я думаю, что мне нужен обработчик данных или обработчик состояния ?!
У меня есть мой главный app.tsx, Filter.tsx для комбо-боксов, grid.tsx для доступных записей и common_models.ts для интерфейсов.
app.tsx:
import * as React from 'react';
import { IGridData, Icbo } from '../model/common_models';
import Filter from '../src/Filter';
import Grid from '../src/Grid';
import '../src/App.css';
interface IMyCompomentState {
ALL_DATA: IGridData[];
BG_DATA: Icbo[];
}
let datadefs: any;
interface IMyCompomentProps {
data?: any;
}
class App extends React.Component<IMyCompomentProps, IMyCompomentState> {
constructor(props: IMyCompomentProps) {
super(props);
this.state = {
ALL_DATA: [],
BG_DATA: []
};
}
public componentWillMount() {
this.getALL_DATA();
setTimeout(() => {
datadefs = this.setBGData(this.state.ALL_DATA)
this.setState({ BG_DATA: datadefs })
}
, 2000);
}
public getALL_DATA() {
this.setState({
ALL_DATA: [
{
BG_ID: 7,
BG: 'Business Group 1',
BU_ID: 15,
BU: 'Business Unit 11',
Vendor: 'Vendor xx',
PM: 'Unasigned',
PM_ID: 5
},
{
BG_ID: 9,
BG: 'Business Group 2',
BU_ID: 17,
BU: 'Business Unit 22',
Vendor: 'Vendor xx',
PM: 'Unasigned',
PM_ID: 5
},
{
BG_ID: 10,
BG: 'Business Group 3',
BU_ID: 16,
BU: 'Business Unit 33',
Vendor: 'Vendor zz',
PM: 'Mario',
PM_ID: 22
},
{
BG_ID: 10,
BG: 'Business Group 3',
BU_ID: 16,
BU: 'Business Unit 33',
Vendor: 'Vendor zz',
PM: 'Luigi',
PM_ID: 14
},
{
BG_ID: 9,
BG: 'Business Group 2',
BU_ID: 4,
BU: 'Business Unit 44',
Vendor: 'Vendor zz',
PM: 'Mario',
PM_ID: 22
},
{
BG_ID: 9,
BG: 'Business Group 2',
BU_ID: 4,
BU: 'Business Unit 44',
Vendor: 'Vendor zz',
PM: 'Luigi',
PM_ID: 14
},
{
BG_ID: 7,
BG: 'Business Group 1',
BU_ID: 1,
BU: 'Business Unit 55',
Vendor: 'Vendor aaa',
PM: 'Link',
PM_ID: 55
},
{
BG_ID: 7,
BG: 'Business Group 1',
BU_ID: 5,
BU: 'Business Unit 66',
Vendor: 'Vendor aaa',
PM: 'Zelda',
PM_ID: 10
},
{
BG_ID: 8,
BG: 'Business Group 4',
BU_ID: 12,
BU: 'Business Unit 77',
Vendor: 'Vendor aaa',
PM: 'Zelda',
PM_ID: 10
},
{
BG_ID: 9,
BG: 'Business Group 2',
BU_ID: 13,
BU: 'Business Unit 88',
Vendor: 'Vendor aaa',
PM: 'Unasigned',
PM_ID: 5
}
]
});
}
public setBGData(data: any[]) {
let Definitions: any = [];
data.map(obj => {
Object
.keys(obj)
.map(val => {
const mappedData = {
key: obj.BG_ID,
text: obj.BG
}
Definitions.push(mappedData);
})
})
Definitions = Definitions.filter((column: any, index: any, self: any) =>
index === self.findIndex((colAtIndex: any) => (
colAtIndex.key === column.key
))
)
return Definitions;
}
public render() {
console.log(this.state.ALL_DATA);
console.log(this.state.BG_DATA);
return (
<div>
<div className="ms-Grid" dir="ltr">
<div className="ms-Grid-row">
<div className="titelMenu">
<div className="ms-Grid-col ms-lg6">
<label> Filter </label>
</div>
</div>
</div>
<div className="ms-Grid-row">
<div className="ms-Grid-col ms-lg2">
<label> YEAR </label>
<Filter cbo={this.state.BG_DATA} />
</div>
<div className="ms-Grid-col ms-lg2">
<label> Business Group </label>
<Filter cbo={this.state.BG_DATA} />
</div>
<div className="ms-Grid-col ms-lg2">
<label> Business Unit </label>
<Filter cbo={this.state.BG_DATA} />
</div>
</div>
<div className="ms-Grid-row">
<div className="ms-Grid-col ms-lg2">
<label> Vendor </label>
<Filter cbo={this.state.BG_DATA} />
</div>
<div className="ms-Grid-col ms-lg2">
<label> Product Manager </label>
<Filter cbo={this.state.BG_DATA} />
</div>
</div>
<div className="ms-Grid-row">
<div className="ms-Grid-col ms-lg12">
<label> Grid 1 </label>
<Grid data={this.state.ALL_DATA} />
</div>
</div>
</div>
</div>
);
}
}
export default App;
Filter.tsx:
import { ComboBox } from 'office-ui-fabric-react';
import { initializeIcons } from 'office-ui-fabric-react/lib/Icons';
import * as React from 'react';
import { Icbo } from '../model/common_models';
interface IMyCompomentState {
data?: any;
}
interface IMyCompomentProps {
cbo: Icbo[];
}
class Filter extends React.Component<IMyCompomentProps, IMyCompomentState> {
constructor(props: IMyCompomentProps) {
super(props);
}
public render() {
initializeIcons();
return (
<div>
<ComboBox
// onChange={this.onchangedaaa}
autoComplete="on"
options={this.props.cbo}
/>
</div>
);
}
}
export default Filter;
Grid.tsx:
import * as React from 'react';
import {
DetailsList,
DetailsListLayoutMode,
IColumn
} from 'office-ui-fabric-react/lib/DetailsList';
import { IGridData } from '../model/common_models';
import { DefaultButton } from 'office-ui-fabric-react';
const Columns: IColumn[] = [
{
key: 'BG',
name: 'BG',
fieldName: 'BG',
minWidth: 100,
maxWidth: 200,
isResizable: true,
ariaLabel: 'Operations for value'
},
{
key: 'BU',
name: 'BU',
fieldName: 'BU',
minWidth: 100,
maxWidth: 200,
isResizable: true,
ariaLabel: 'Operations for name'
},
{
key: 'Vendor',
name: 'Vendor',
fieldName: 'Vendor',
minWidth: 100,
maxWidth: 200,
isResizable: true,
ariaLabel: 'Operations for name'
},
{
key: 'PM',
name: 'PM',
fieldName: 'PM',
minWidth: 100,
maxWidth: 100,
isResizable: true,
ariaLabel: 'Operations for name'
},
{
key: 'Delete',
name: 'Delete',
fieldName: 'delete',
minWidth: 50,
maxWidth: 100,
isResizable: true,
ariaLabel: 'Operations for value'
}
];
interface IMyCompomentState {
data: IGridData[];
}
interface IMyCompomentProps {
data: IGridData[];
}
export class Grid extends React.Component<IMyCompomentProps, IMyCompomentState>
{
constructor(props: IMyCompomentProps) {
super(props);
console.log(this.props)
this.state = {
data: []
};
console.log(this.state.data);
}
public render() {
return (
<div>
<DetailsList
items={this.props.data}
columns={Columns}
setKey="set"
layoutMode={DetailsListLayoutMode.fixedColumns}
onItemInvoked={this._onItemInvoked}
onRenderItemColumn={this._onRenderItemColumn}
/>
</div>
);
}
public _onItemInvoked(item: any): void {
alert(`Doppelklick: ${item.BU}`);
}
private _onRenderItemColumn(item: any, index: number, column: IColumn): JSX.Element {
if (column.fieldName === 'delete') {
return <DefaultButton>+</DefaultButton>;
}
return item[column.fieldName!];
}
}
export default Grid;
common_models.ts:
export interface IGridData {
BG_ID: number;
BG: string;
BU_ID: number;
BU: string;
Vendor: string;
PM: string;
PM_ID: number;
}
export interface Icbo {
key: number;
text: string;
}
Я благодарен за любой ответ, который поможет мне решить проблему.
Спасибо!