Работаю с данной компонентой. Все отрисовывается хорошо, выделение итемов работает,но почему-то нет скролла.Выводится только 21 итем и все.Хотя если регулировать высоту блока,то видно.что в массиве 500 итемов.В чем может быть ошибка?
export default class Example extends Component {
constructor(props) {
super(props);
if (_items.length === 0) {
for (let i = 0; i < 200; i++) {
_items.push({
key: i,
name: 'Item ' + i,
value: i
});
}
}
this._selection = new Selection({
onSelectionChanged: () => this.setState({ selectionDetails: this._getSelectionDetails() })
});
this.state = {
items: _items,
selectionDetails: this._getSelectionDetails()
};
}
render(){
let {
items,
selectionDetails
} = this.state;
return (
<div>
<MarqueeSelection selection={ this._selection } style={{'overflow':'auto'}}>
<DetailsList
items={ items }
columns={ _columns }
setKey='set'
layoutMode={ DetailsListLayoutMode.fixedColumns }
selection={ this._selection }
selectionPreservedOnEmptyClick={ true }
onItemInvoked={ (item) => alert(`Item invoked: ${item.name}`) }
/>
</MarqueeSelection>
</div>
);
}
_getSelectionDetails = () => {
let selectionCount = this._selection.getSelectedCount();
switch (selectionCount) {
case 0:
return 'No items selected';
default:
return `${selectionCount} items selected`;
}
};
}
1) Чтобы была прокрутка надо style={{'overflow':'auto'}}
передать в div
, а не в MarqueeSelection
2) По поводу динамической подгрузки айтемов:
Первое, что нам нужно сделать - это передать в div
обработчик onScroll
и получить ссылку на его node с помощью ref
:
<div
onScroll={this.handleScroll}
ref={el => this.scroll = el}>
Далее получим ссылку на сам список и закешируем его высоту:
componentDidMount(){
this.detailList=this.scroll.childNodes[0];
this.scrollHeight = this.scroll.clientHeight
}
Теперь нам надо получить предельное значение scrollTop
по достижению которого мы будем подгружать айтемы. Первое, что скорее всего прийдет в голову - это получать его в componentDidUpdate
, но это ошибочное решение, т.к. DetailsList
- это ассинхронный компонент и сразу после того как наш компонент примонтируется, там айтемов не будет и его высота будет 0. Поэтому воспользуемся onDidUpdate
самого DetailsList
. Стоит заметить, что вызывается он не только при апдейте, но и при первом рендере айтемов.
<DetailsList
onDidUpdate={this.handleDetailListUpdate}
И сам обработчик:
handleDetailListUpdate=()=>{
this.maxScrollTop=this.detailList.clientHeight-this.scrollHeight-100;
}
Ну и наконец-то обработчик скролла:
handleScroll=()=>{
if (this.scroll.scrollTop>this.maxScrollTop){
this.setState({
items: this.state.items.concat(this.getItems()),
});
}
}
Функция getItems()
для теста:
startNum = 0;
getItems(){
const items = [];
const finishNum = this.startNum + 50;
for (let i = this.startNum; i<finishNum; i++) {
items.push({
key: i,
name: 'Item ' + i,
value: i
});
}
this.startNum += 50;
return items;
}
Ну и не забудем получить первую порцию айтемов в конструкторе:
constructor(props) {
super(props);
this.state = {
items: this.getItems(),
selectionDetails: this._getSelectionDetails()
};
}
Вот и все.
Ну и на всякий случай код всего компонента:
export default class Example extends Component {
constructor(props) {
super(props);
this._selection = new Selection({
onSelectionChanged: () => this.setState({ selectionDetails: this._getSelectionDetails() })
});
this.state = {
items: this.getItems(),
selectionDetails: this._getSelectionDetails()
};
}
startNum = 0;
getItems(){
const items = [];
const finishNum = this.startNum + 50;
for (let i = this.startNum; i<finishNum; i++) {
items.push({
key: i,
name: 'Item ' + i,
value: i
});
}
this.startNum += 50;
return items;
}
componentDidMount(){
this.detailList=this.scroll.childNodes[0];
this.scrollHeight = this.scroll.clientHeight
}
handleScroll=()=>{
if (this.scroll.scrollTop>this.maxScrollTop){
this.setState({
items: this.state.items.concat(this.getItems()),
});
}
}
handleDetailListUpdate=()=>{
this.maxScrollTop=this.detailList.clientHeight-this.scrollHeight-100;
}
render(){
let {
items,
selectionDetails
} = this.state;
return (
<div
style={{height:'800px', overflow:'auto' }}
onScroll={this.handleScroll}
ref={el => this.scroll = el}>
<MarqueeSelection selection={ this._selection }>
<DetailsList
onDidUpdate={this.handleDetailListUpdate}
/>
</MarqueeSelection>
</div>
);
}
_getSelectionDetails = () => {
let selectionCount = this._selection.getSelectedCount();
switch (selectionCount) {
case 0:
return 'No items selected';
default:
return `${selectionCount} items selected`;
}
};
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Как селектором :not или методом not() исключить из обернутого набора вложенный элемент? Есть такая структура:
Никак не могу разобраться, как реализовать модели в Expressjs? Подскажите ресурсы, где описано, как это сделать
Есть ряд элементов, при клике по каждому, оно должно удаляться таким образом, что после перезагрузки страницы, элемент будет отсутствоватьСамо...