Проблема с потоком данных между Angular компонентами - PullRequest
0 голосов
/ 05 августа 2020

У меня есть структура веб-страницы, подобная следующей:

page layout

  • Button should select/unselect all the rows of the table.
  • Button and Table are separate components injected into the page.
  • Table is using Material's SelectionModel.

From the page I'm reaching selection.selected of the Table through @ViewChild decorator. Its easy to place the selection logic in the page as it's where the table is injected, but this requires to place the same logic in every page where the button needs to be.
I'd like to simplify this by placing the logic inside the Button component so all that should be done to have the functionality is to insert its selector into page's template. But there's a catch I can't overcome:

How to reach selection.selected of the Table from the Button component?

What is the best practice to achieve this?

Here's how does it look like in the Page class

    @ViewChild(TableComponent)
    private table: TableComponent;


    // ...


    checkAll(): void {
        const numSelected = this.table.selection.selected.length;
        const numRows = this.table.dataSource.data.length;
        const result = numSelected === numRows;
        result
            ? this.table.selection.clear()
            : this.table.dataSource.data.forEach(row => this.table.selection.select(row));
    }

А вот шаблон html файла:

    <button (click)="checkAll()">Check all</button>
    <app-table></app-table>

Ответы [ 2 ]

1 голос
/ 05 августа 2020

Вы можете использовать Rx JS s Subject, ввести его в сервис, который вы вставите через конструктор как в компоненты кнопки, так и в таблицы. Реализация вашей службы может выглядеть следующим образом:

// service
export class TableService {
    private event: Subject<void> = new Subject<void>();
    public event$ = this.event.asObservable();

    public emitEvent(event?: MouseEvent): void {
        this.event.next();
    }
}

Затем вы берете эту службу и вставляете ее в компонент кнопки:

// button component
export class Button {

    constructor(private tableService: TableService) {}

    update(): void {
        this.tableService.emitEvent();
    }
}

вы можете активировать update () Функция при нажатии в файле шаблона html. Затем реализуйте логику выбора c в своей таблице и просто используйте event$, чтобы вызвать его:

// table component
export class Table {

    constructor(private tableService: TableService) {
        this.tableService.event$.subscribe(() => this.checkAll());
    }

    checkAll(): void {
        // your selection logic goes here
    }
}
1 голос
/ 05 августа 2020

Воспользуйтесь услугой с Rx JS Subject. Сервис может быть внедрен как в компонент кнопки, так и в компонент таблицы. Через конструктор. Когда кнопка нажата, вы запускаете объект службы, на который подписан компонент таблицы. Google 'subject service angular'

В качестве альтернативы вы можете создать компонент, включающий кнопку и таблицу. Тогда кнопка не должна быть компонентом. И нажатие кнопки logi c будет реализовано только один раз.

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