Вызов метода Angular в шаблоне

В шаблоне angular я пытаюсь загрузить строки таблицы с помощью ng for. У меня также есть условный контент в определенных столбцах, который загружает разметку на основе значений другого столбца. (код показан в конце)

Проблема, с которой я столкнулся, заключается в том, что даже если я перемещаю указатель мыши по этой странице, в консоли браузера я вижу сообщение «isElposedForVacDays выполнено» несколько раз. Когда я говорю несколько раз, это буквально более 1000 раз за 4 секунды, просто быстро перемещая мышь по странице.

Как мне избежать этого и убедиться, что он выполняется только один раз? Я использую аналогичный синтаксис ngif = 'method-call ()' в 5 местах. Я читал, что мы можем использовать чистые каналы, и я также тестировал, и он не выполнялся несколько раз.

Хотелось бы узнать, как правильно решить эту проблему. Спасибо, что нашли время прочитать мой вопрос.

См. ниже.

Разметка шаблона для одной строки

 <mat-cell class = "actions center " *matCellDef = "let employeeRow">
     <span  *ngIf = "isEligibleForVacDays(employeeRow)"
            class = "actionIcon"
            (click) = "onReloadClick(employeeRow)"
            matTooltip = "Eligible for Vacation Days">
            <i class = "fa fa-refresh fa-2x" aria-hidden = "true"></i>
                </span>
    </mat-cell>

Функция в файле машинописного текста компонента

    isEligibleForVacDays()
{   
    console.info('isEligibleForVacDays executed')
    let isEligibleForVacDays = false;

    some complex logic based on instance variables set on the component

    // finally returning true or false
    return isEligibleForReload;
}

Где-то у вас есть что-то, что вызывает добавление слушателя мыши к таблице (или документу), и этот слушатель выполняет свою работу внутри зоны Angular, вызывая выполнение изменения обнаружения всякий раз, когда вы перемещаете мышь. Если это нормально и не вызывает проблем с производительностью / энергопотреблением, тогда просто не обращайте на это внимания. Если нет, найдите и исправьте.

JB Nizet 15.06.2018 00:16

Если все ваши ячейки имеют matTooltip, каждый mouseEnter / mouseLeave в каждой ячейке будет вызывать такие изменения. Но еще раз, если у вас есть 1000 журналов за 4 секунды, это означает, что каждое изменение происходит очень быстро (250 компакт-дисков в секунду), и вам не следует об этом заботиться: просто удалите свой console.info ().

JB Nizet 15.06.2018 00:23

@JBNizet Спасибо за ответ. Есть ли лучший способ справиться с этим сценарием, поскольку он настолько распространен, что иногда компонент может иметь много ngif (ов) с вызовами методов. Есть ли встроенная конструкция angular, которая намекнет Angular, что вы выполняете ее без необходимости и выполняете ее один раз?

hp8888 15.06.2018 01:28
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
4
3
2 286
2

Ответы 2

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

От документация по angular:

Angular executes a pure pipe only when it detects a pure change to the input value. A pure change is either a change to a primitive input value (String, Number, Boolean, Symbol) or a changed object reference (Date, Array, Function, Object).

Единственное, что следует помнить, это то, что если вам нужно повторно оценить условие, вам нужно будет изменить ссылку на объект (например, используя Object.assign или распространение)

Спасибо за ответ. Я хочу использовать канал, но мне кажется странным, что внутри директивы ng if он использует канал для получения своего значения. Просто хотел убедиться, что такие трубы можно использовать. Я понимаю, что асинхронный канал используется с ng-if, но я думал, что его встроенный канал и рекомендуется на angular.io.

hp8888 15.06.2018 01:32

На мой взгляд, каналы предназначены для использования либо для фильтрации, либо для преобразования данных перед их отображением, что вы и делаете здесь. С учетом сказанного, пока нет влияния на производительность, не должно быть проблем, если метод будет вызываться 1000 раз каждые 4 секунды, если он не выполняет HTTP-вызовы, поэтому оставив его как есть, может быть хороший вариант.

Maxime Michaud 15.06.2018 01:42

Очень простой способ решить вашу проблему - изменить метод обнаружения изменений вашего компонента на OnPush.

@Component({
  selector: 'app-YOUR-COMPONENT',
  templateUrl: './YOUR-COMPONENT.component.html',
  styleUrls: ['./YOUR-COMPONENT.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})

Но вам придется обнаруживать изменения вручную.

constructor( private change: ChangeDetectorRef) {}

isEligibleForVacDays() {
  // do something
  this.change.detectChanges();
}

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