Как показать мат-спиннер для каждой строки в мат-таблице в angular 6

У меня есть мат-таблица, в которой отображается список выполняемых заданий. Я создал две кнопки (Stop и Re-Run) рядом с каждой строкой. Однако я хочу создать мат-спиннер, который будет отображаться только при выполнении задания или когда пользователь нажимает кнопку повторного запуска. Я создал счетчик, но он отображается для всех строк, когда я нажимаю кнопку повторного запуска. Как мне показать это только для строки, на которую я нажал.

Мой HTML-код:

 <!--  Code for Stop and Re-Run Buttons -->
        <ng-container matColumnDef = "actions">
            <mat-header-cell *matHeaderCellDef> </mat-header-cell>
            <mat-cell *matCellDef = "let element; let index = index">
                <button
                    mat-icon-button
                    (click) = "stop_exec_job(element)"
                    matTooltip = "Stop Executing the Job"
                    [disabled] = "element.status == 'Completed'"
                >
                    <!-- Edit icon for row -->
                    <i class = "material-icons" style = "color:red"> stop </i>
                </button>
                <!-- Delete icon for row -->
                <button
                    mat-icon-button
                    (click) = "re_run_job(element)"
                    matTooltip = "Re-Run the Job"
                    [disabled] = "
                        element.status == 'Running' ||
                        element.status == 'Pending'
                    "
                >
                    <i class = "material-icons" style = "color:green">
                        cached
                    </i>
                </button>
            </mat-cell>
        </ng-container>
        <!-- Code for Spinner -->
        <ng-container matColumnDef = "spinner">
            <mat-header-cell *matHeaderCellDef> </mat-header-cell>
            <mat-cell *matCellDef = "let element">
                <div *ngIf = "displaySpinner;else doNotShowSpinner">
                    <mat-spinner></mat-spinner>
                </div>
                <ng-template #doNotShowSpinner>

                </ng-template>
            </mat-cell>
        </ng-container>

        <mat-header-row
            *matHeaderRowDef = "jobExecStatDisplayedColumns"
        ></mat-header-row>
        <mat-row
            *matRowDef = "
                let row;
                columns: jobExecStatDisplayedColumns;
                let element
            "
            class = "element-row"
        >
        </mat-row>

Код машинописного текста:

displaySpinner: boolean = false;

stop_exec_job(element) {
    if (element.status == "Running" || element.status == "Pending") {
        //Api to stop Job Execution
        this.recommendationService
            .stopJobExecution(element.jobId, "Cancelled")
            .subscribe(data => {
                this.executeJobStop = data;
                //this.changeStatus.push(this.executeJobStop);
                // this.newStatus = new ExampleDataSource();
            });
        this.displaySpinner = false;
        element.status = "Completed";
        this.snakbar.statusBar("Job Execution Stopped", "Sucess");
    } else {
        this.snakbar.statusBar("Job Failed to start", "Failure");
    }
}

re_run_job(element) {
    if (
        element.status == "Cancelled" ||
        element.status == "Completed" ||
        element.status == "Executed" ||
        element.status == "FINISHED"
    ) {
        //Api to Re-Run Job Execution
        this.recommendationService
            .stopJobExecution(element.jobId, "Running")
            .subscribe(data => {
                this.executeJobStop = data;
                //this.changeStatus.push(this.executeJobStop);
                // this.newStatus = new ExampleDataSource();
            });
        this.displaySpinner = true;
        element.status = "Running";
        this.snakbar.statusBar("Job Execution Started", "Sucess");
    } else {
        this.snakbar.statusBar("Job Failed to start", "Failure");
    }
}

Кнопка остановки и повторного запуска работает нормально. Если я нажму «Стоп» в строке 2, изменится только статус строки 2. Но если я нажму на запуск строки 1, то счетчик начнет отображаться для всех строк и аналогично для остановки.

вам нужно установить displaySpinner внутри каждого объекта элемента вместо глобальной переменной. Потому что это цикл, и вам нужно проверять логику displaySpinner для каждой строки, а не глобальную единственную переменную.

Kajol Chaudhary 29.01.2019 06:59
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
2 619
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ваше свойство displaySpinner (глобальное свойство) класса используется во всех строках. Вот почему, когда вы нажимаете Re-Run, displaySpinner переключается на true, и, поскольку все строки имеют условие для одного и того же свойства, все они показывают счетчик.

Вместо использования displaySpinner попробуйте использовать element.status.

Измените строки ниже:

<div *ngIf = "displaySpinner;else doNotShowSpinner">
    <mat-spinner></mat-spinner>
</div>

ниже:

<div *ngIf = "element.status === 'Running';else doNotShowSpinner">
    <mat-spinner></mat-spinner>
</div>

Свяжите счетчик со статусом элемента:

<!-- Code for Spinner -->
        <ng-container matColumnDef = "spinner">
            <mat-header-cell *matHeaderCellDef> </mat-header-cell>
            <mat-cell *matCellDef = "let element">
                <div *ngIf = "element.status === 'Running'">
                    <mat-spinner></mat-spinner>
                </div>
                <ng-template #doNotShowSpinner>

                </ng-template>
            </mat-cell>
        </ng-container>

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

Ответ принят как подходящий

Причина, по которой функция stop_exec_job изменяет только статус выбранных строк, заключается в том, что вы фактически устанавливаете статус строк element, которые вы передаете функции.

Ваша функция re_run_job также устанавливает статус (это нормально), но проблема в том, что вы используете одну переменную displaySpinner в своем компоненте для управления видимостью все счетчиков в каждой строке.

To solve your problem, add an additional property on your element's which stores the status of the spinner for each row separately (e.g. displaySpinner).

Или, если счетчик основан на статусе элемента, вы можете изменить свой HTML, чтобы он выглядел примерно так (и избавиться от вашей переменной displaySpinner):

<div *ngIf = "element.status === 'Pending' || element.status === 'Running'">
  <mat-spinner></mat-spinner>
</div>

Другие вопросы по теме