Сортировка матов не работает, даже если моя переменная источника данных _sort изменилась - PullRequest
0 голосов
/ 30 октября 2018

В приложении Angular я загружаю данные из базы данных, используя

data.service.ts

import {Injectable} from '@angular/core';
import {Post} from '../Post';
import {Observable, of} from 'rxjs';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class DataService {

constructor(private http: HttpClient) {
}

getData(): Observable<Post[]> {
    return this.http.get<Post[]>('http://localhost:80/Findall');
}

getCategories() {
    return this.categories;
}

findCaldera(index: string) {
    console.log('find: ' + index);
    return this.http.get('http://localhost:80/Find/' + index);
}

updateCaldera(index: string, data) {
    console.log('find: ' + index);
    return this.http.put('http://localhost:80/Update/' + index, data);
}

addPost(data) {
    console.log('add: ' + JSON.stringify(data));
    return this.http.post<Post>('http://localhost:80/Add', data);
}

deletePost(index: string) {
    console.log('delete: ' + index);
    return this.http.delete('http://localhost:80/Delete/' + index,     {responseType:'text'});
}
}

Таким образом, это возвращает наблюдаемую информацию на мою приборную панель, где отображаются данные

dashboard.component.ts

import {Component, ViewChild} from '@angular/core';
import {DataService} from '../data/data.service';
import {Post} from '../Post';
import {DataSource} from '@angular/cdk/table';
import {Observable} from 'rxjs/Observable';
import {AuthService} from '../auth.service';

import {PostDialogComponent} from '../post-dialog/post-dialog.component';
import {EditComponent} from '../edit/edit.component';
import {MatDialog, MatSort, MatTableDataSource} from '@angular/material';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent {
  constructor(private dataService: DataService, public auth: AuthService, public dialog: MatDialog) {
  }
  @ViewChild(MatSort) sort: MatSort;

  displayedColumns = ['Borrower1','_id', 'edit','delete'];
  dataSource: PostDataSource |null;
  ngOnInit(){
    this.dataSource = new PostDataSource(this.dataService, this.sort);
  }

  ngAfterViewInit(){
    this.sort.sortChange.subscribe(()=>{console.log(this.dataSource)});
  }


  deletePost(id) {
    if (this.auth.isAuthenticated()) {
      this.dataService.deletePost(id).subscribe(()=>{
        this.dataSource = new PostDataSource(this.dataService, this.sort);
      }); 
    } else {
      alert('Login in Before');
    }
  }

  editDialog(id): void {
    let dialogRef = this.dialog.open(EditComponent, {
      width: '100%',
      data: id,

    });
    dialogRef.componentInstance.event.subscribe((result) => {
      console.log(result.data)
      this.dataSource = new PostDataSource(this.dataService, this.sort);
    });
  }

  openDialog(): void {
    let dialogRef = this.dialog.open(PostDialogComponent, {
      width: '100%',
      data: 'Add Post'
    });
    dialogRef.componentInstance.event.subscribe((result) => {
      console.log(result.data)
      this.dataService.addPost(result.data).subscribe(()=>{
        this.dataSource = new PostDataSource(this.dataService, this.sort);
      });
    });
  }
}



export class PostDataSource extends DataSource<any> {
  constructor(private dataService: DataService, private _sort: MatSort) {
    super();
  }

  connect(): Observable<Post[]> {
    console.log("hi1")
    return this.dataService.getData();
  }

  disconnect() {
  }
}

Когда я нажимаю на стрелку сортировки на html-странице, происходит событие, как я вижу из this.sort.sortChange.subscribe(()=>{console.log(this.dataSource)});

внутри источника данных свойство _sort изменяется, чтобы отразить изменения, которые я делаю, щелкнув стрелку сортировки в представлении, т.е. после 1 щелкните dataSource._sort.order = "asc", а затем после другого нажмите dataSource._sort.order = "desc". Однако данные в таблице не меняются. Есть много примеров использования MatTableDataSource, но я читал, что не рекомендуется использовать это при использовании http для получения моих данных.

Спасибо

1 Ответ

0 голосов
/ 30 октября 2018

Когда вы используете MatSort с асинхронными данными, вы должны прослушать изменения сортировки и для каждого сделать вызов для сортировки данных.

Вот пример. Я надеюсь, что это поможет.

Пример Stackblitz

ОБНОВЛЕННЫЙ ОТВЕТ

Если вы используете DataSource, ваши данные не будут сортироваться автоматически, вам придется прослушивать изменения сортировки. Одним из способов сделать это может быть следующий

import { startWith } from 'rxjs/operators';
import { combineLatest } from 'rxjs';

export class PostDataSource extends DataSource<any> {
  constructor(private dataService: DataService, private _sort: MatSort) {
    super();
  }

  connect(): Observable<Post[]> {
    return combineLatest(
      this.dataService.getData(),
      this.sort.sortChange.pipe(startWith(null)),
      (data, sort) => {
        return this.sortData(data, sort);
      }
    )
  }

  disconnect() {
  }

  sordData(data, sort) {
     // Sort data
     return this.data;
  }
}

Обратите внимание, что sortChange имеет startWith. Это потому, что для ОбъединитьПоследние требуется, чтобы все наблюдаемые излучали хотя бы один раз

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...