简体   繁体   中英

ReactJS (Typescript + Fabric UI) - State or Data Handler?

I'm new in ReactJs and need Help. I have 4 Comboboxes and they must interact together. So at first level i have business Group, second business unit, third is vendor and fourth is product manager.

If i choose an entry in business group the options in the comboboxes (unit, vendor, manager) should be refreshed. But also if i choose an vendor (third level) the business group, unit and product manager comboboxes should only have the options for the selected vendor.

I have an Array when app.tsx will mount. I splitted this array for the business group and fill all comboboxes. Is this the right way for splitting? And how can the comboboxes interact together. I think i need a data handler oder state handler?!

i have my main app.tsx, a Filter.tsx for the comboxes, a grid.tsx for the available entries and a common_models.ts for the interfaces.

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; 
}

I'm grateful for any answer that helps me to solve the problem.

Thanks!

i make a workaround with Material UI with one handleChange for alle Select Boxes.

Here is also a Link for the Solution: Creating dependant fields in Reactjs?

                    <div className="ms-Grid-col ms-lg2">
                        <Select
                            fullWidth={true}
                            value={this.state.BG_selected}
                            onChange={this.handleChange}
                            inputProps={{
                                name: 'Groupy'
                            }}
                            autoWidth={true}
                        >
                            {this.state.BG_DATA.map(item => (
                                <MenuItem key={item.key} value={item.key}>
                                    {item.text}
                                </MenuItem>
                            ))}
                        </Select>
                        <FormHelperText>Select Business Group</FormHelperText>
                    </div>
                    <div className="ms-Grid-col ms-lg2">
                        <Select
                            fullWidth={true}
                            value={this.state.BU_selected}
                            onChange={this.handleChange}
                            inputProps={{
                                name: 'Unity'
                            }}
                            autoWidth={true}
                        >
                            {this.state.BU_DATA.map(item => (
                                <MenuItem key={item.key} value={item.key}>
                                    {item.text}
                                </MenuItem>
                            ))}
                        </Select>
                        <FormHelperText>Select Business Unit</FormHelperText>
                    </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM