ОК, я смог подражать тому, что я сделал в Angular 6, то есть создать заметку, на которую можно подписаться (прислушиваться к изменениям)
Во-первых, сервис order-item-service .jsx:
import { Subject } from 'rxjs';
import { ajax } from "rxjs/ajax";
import { Observable } from "rxjs";
const subject = new Subject();
const base_url = 'https://localhost:5001/OrderItem';
export let orderItemByDivision = {
data: []
}
export const getOrderItemByDiv = (div, yr) => {
return new Observable(observe => {
orderItemByDivision.data = ajax
.get(base_url + "/" + div + "/" + yr)
.subscribe(resu => {
orderItemByDivision.data = resu.response ;
observe.next(resu.response);
});
});
};
export const messageService = {
sendMessage: message => subject.next({ message }),
clearMessage: () => subject.next(),
getMessage: () => subject.asObservable()
}
Как видите, я пытался использовать Subject из rx js для отправки данных между компонентами, но использование ajax из rxjs / ajax было тем, что в конечном итоге привело меня чтобы иметь возможность прослушивать изменения
Я продолжил то же самое с сервисом Division-Service.jsx:
import { ajax } from "rxjs/ajax";
import { Observable } from "rxjs";
const base_url = 'https://localhost:5001/Division';
let state = {
data: []
}
export const getDivision = () => {
return new Observable(observe => {
state.data = ajax
.get(base_url)
.subscribe(resu => {
state.data = resu.response ;
observe.next(resu.response);
});
});
}
Как вы можете видеть в обоих случаях, он создает на наблюдаемом после него подписывается на метод get - другими словами, каждый раз, когда используется URL-адрес API, он будет предупреждать любого, кто подписан на два вышеупомянутых метода.
Следующий компонент Division-dropdown-component.jsx получает: деление JSON, заполняющее выпадающее меню делений. Как только конечный пользователь нажимает на подразделение, подписывается getOrderItemByDiv, который возвращает JSON, который нам нужен для заполнения таблицы @ material-ui, перечисленной ниже:
import React from "react";
import {
FormGroup,
FormControl,
Button,
Menu,
MenuItem
} from "@material-ui/core";
import { getDivision } from "../services/division-service";
import { getOrderItemByDiv } from "../services/order-item-service";
import { MuiThemeProvider } from "@material-ui/core/styles";
import theme from "../theme";
import { messageService } from "../services/order-item-service";
export default class DivisionDropDownComponent extends React.Component {
state = {
divData: [],
divValue: "Select Division",
divOpen: false,
divAnchorEl: null,
yrValue: "2020",
yrOpen: false,
yrAnchorEl: null,
yrs: [
"2020",
"2019",
"2018",
"2017",
"2016",
"2015",
"2014",
"2013",
"2012"
]
};
constructor(props) {
super(props);
this.handleDivChange = this.handleDivChange.bind(this);
}
componentDidMount() {
getDivision().subscribe(res => {
this.setState({ divData: res });
});
}
handleDivChange = divData => {
getOrderItemByDiv(divData.code_division, this.state.yrValue).subscribe(
res => {
this.setState({ divData: res });
messageService.sendMessage(res);
}
);
this.onCloseDiv();
};
handleYrChange = event => {
this.setState({ yrValue: event.target.value });
this.onCloseYr();
};
handleDivClick = event => {
this.setState({ divAnchorEl: event.target });
this.setState({ divOpen: true });
};
handleYrClick = event => {
this.setState({ yrAnchorEl: event.target });
this.setState({ yrOpen: true });
};
onCloseDiv = () => {
this.setState({ divOpen: false });
};
onCloseYr = () => {
this.setState({ yrOpen: false });
};
render() {
let arrayOfData = this.state.divData;
let dropdowns = arrayOfData.map((divData, index) => (
<MenuItem
onClick={event => this.handleDivChange(divData)}
key={index}
value={divData.code_division}
text={divData.code_division}
>
{divData.code_division}
</MenuItem>
));
let arrayOfYrs = this.state.yrs;
let yrDropDown = arrayOfYrs.map(yrs => (
<MenuItem
onClick={event => this.handleYrChange(event)}
value={yrs}
key={yrs}
>
{yrs}
</MenuItem>
));
return (
<MuiThemeProvider theme={theme}>
<FormGroup column="true">
<FormControl>
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={this.handleYrClick}
>
Select Year
</Button>
<Menu
id="yrs-menu"
open={this.state.yrOpen}
anchorEl={this.state.yrAnchorEl}
onClose={this.onCloseYr}
defaultValue={this.state.yrValue ? this.state.yrValue : ""}
>
{yrDropDown}
</Menu>
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={this.handleDivClick}
>
Select Division
</Button>
<Menu
id="div-menu"
anchorEl={this.state.divAnchorEl}
open={this.state.divOpen}
onClose={this.onCloseDiv}
className="dropDownDiv"
defaultValue={this.state.divValue ? this.state.divValue : ""}
>
<MenuItem value="Select Division">Select Division</MenuItem>
{dropdowns}
</Menu>
</FormControl>
</FormGroup>
</MuiThemeProvider>
);
}
}
Ниже приводится Компонент order-item-component.jsx, который заполняет material-ui Таблица:
import React from "react";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
import { TablePagination } from "@material-ui/core";
import TableFooter from "@material-ui/core/TableFooter";
import { messageService } from "../services/order-item-service";
export default class OrderItemComponent extends React.Component {
state = {
data: [],
_columns: [],
Header: [],
totalCount: 10,
pageSize: 16,
page: 0
};
componentDidMount() {
componentDidMount() {
this.subscription = messageService.getMessage().subscribe(message => {
if (message) {
this.setState({ data: message.message });
this.setState({ totalCount: Math.ceil(this.state.data.length / this.state.pageSize) });
this.setState({ Header: ['order_id', 'order_item_id', 'product_id', 'code_division', 'code_product',
'quantity_due', 'quantity_shipped', 'price', 'date_shipped', 'date_due',
'customer_id','ship_via','value_due','value_shipped','date_order','date_modified'] });
} else {
// do nothing
this.setState({ data: [] });
}
})
}
componentWillUnmount() {
// unsubscribe to ensure no memory leaks
this.subscription.unsubscribe();
}
getOrderItem(){
this.setState({ data: messageService.getMessage() });
}
handleChangePage = (event, newPage) => {
this.setState({ page: newPage });
if (this.state.totalCount !== this.state.data.length) {
}
}
render() {
return (
<div>
<TableContainer component={Paper}>
<Table aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Order ID</TableCell>
<TableCell align="right">Qty Due</TableCell>
<TableCell align="right">Prod ID</TableCell>
<TableCell align="right">Div</TableCell>
<TableCell align="right">Prod Code</TableCell>
<TableCell align="right">Qty Sh</TableCell>
<TableCell align="right">Price</TableCell>
<TableCell align="right">Dt SH</TableCell>
<TableCell align="right">Dt Due</TableCell>
<TableCell align="right">Cust ID</TableCell>
<TableCell align="right">Ship Via</TableCell>
<TableCell align="right">Val Dt</TableCell>
<TableCell align="right">Val Sh</TableCell>
<TableCell align="right">Dt Or</TableCell>
<TableCell align="right">Dt Mod</TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.data.map((row, index) => (
<TableRow key={ index }>
<TableCell component="td" scope="row">
{ row.order_id }
</TableCell>
<TableCell align="right">{ row.quantity_due }</TableCell>
<TableCell align="right">{ row.product_id}</TableCell>
<TableCell align="right">{ row.code_division }</TableCell>
<TableCell align="right">{ row.code_product }</TableCell>
<TableCell align="right">{ row.quantity_shipped }</TableCell>
<TableCell align="right">{ row.price }</TableCell>
<TableCell align="right">{ row.date_shipped}</TableCell>
<TableCell align="right">{ row.date_due }</TableCell>
<TableCell align="right">{ row.customer_id }</TableCell>
<TableCell align="right">{ row.ship_via }</TableCell>
<TableCell align="right">{ row.value_due }</TableCell>
<TableCell align="right">{ row.value_shipped }</TableCell>
<TableCell align="right">{ row.date_order }</TableCell>
<TableCell align="right">{ row.date_modified }</TableCell>
</TableRow>
))}
</TableBody>
<TableFooter>
<TableRow>
<TablePagination
rowsPerPageOptions={ [5, 10, 25, { label: 'All', value: -1 }] }
colSpan={ 3 }
count={ this.state.data.length }
rowsPerPage={ this.state.pageSize }
page={ this.state.page }
SelectProps={ {
inputProps: { 'aria-label': 'rows per page' },
native: true,
} }
onChangePage={ this.handleChangePage }
/>
</TableRow>
</TableFooter>
</Table>
</TableContainer>
</div>
)
}
}
Теперь вы можете увидеть, как я использую метод getMessage для установки данных
Почти все это работает, кроме нумерации страниц - когда я нажимаю на стрелку «больше», он будет правильно рассчитывать, какой будет следующий набор данных, но не будет отображать «новые» данные в таблице. Мне нужно будет выяснить, как сделать refre sh для таблицы @ material-ui, когда используется разбиение на страницы, но, тем не менее, я подумал, что поделюсь, если кто-то еще захочет узнать, как создать наблюдаемую область.
Я пытался использовать пример в документации @ material-ui, но setPage = React.useState (5) продолжал вызывать ошибку, связанную с недействительным хуком или чем-то в этом роде - относительно следующей функции:
const handleChangePage = (event, newPage) => {
setPage(newPage);
};
Я опубликую еще один вопрос по этой теме c, но на данный момент на вопрос, который я задал, дан ответ
Еще раз спасибо