Почему входной атрибут вызывается сотни раз при оценке функции - PullRequest
0 голосов
/ 06 июня 2018

Я использую атрибут с контролем доступа, чтобы проверить, должно ли поле быть включено или отключено.

Итак, у меня есть что-то вроде этого:

<input matInput type="text" #name="ngModel" name="application.name" [ngModel]="application?.name" (ngModelChange)="application.name=$event"
              placeholder="Nom de l'application" required [disabled]="isDisabled([permissions.applications.any.update, permissions.applications.own.update], 'name')"[appUnique]="application" [listElem]="applications" key="name" maxlength="255">

Вызвана функция isDisabledсотни раз, когда отображается ввод, и каждое действие в форме вызывает что-то вроде 12 или 32 дополнительных вызовов.

Это вызывает зависание моего браузера.

Есть идеи, почему происходит такое поведение?Это вызвано ZoneJS?

Как сделать так, чтобы к этой функции обращался только один человек?

Редактировать: Реализация директивы

/**
 * Check if the component should be disabled
 */
@Directive({
  selector: "[appIsDisabled]"
})
export class IsDisabledDirective implements OnInit {
  // Listof permission to check 
  @Input("appIsDisabled") permissions: PermissionInterface[];
  // The resource id to be access
  @Input() resourceId: number;
  // The resource type to be access
  @Input() resourceType: string;
   // Attribute to be check(eg: name, firstname... for a user resource)
  @Input() attribute: string;
  constructor(private authService: AuthService, private el: ElementRef, private utilsService: UtilsService, private renderer: Renderer2) {
  }

  ngOnInit() {
    if (!this.authService.hasPermission(this.permissions, this.resourceId, this.resourceType, this.attribute)) {
      this.renderer.setAttribute(this.el.nativeElement, "disabled", "disabled");
    }

  }
}

Ответы [ 3 ]

0 голосов
/ 06 июня 2018

Краткий ответ - ваш метод выполнен угловым в алгоритме обнаружения изменений.Angular сканирует каждую привязку, чтобы обнаружить изменения и действовать соответственно, и делает это довольно часто, и это может происходить много раз за одно событие.Вам нужно узнать о этом процессе и о том, как минимизировать его .Это большая тема, и вдаваться в подробности в SO ответе неуместно, но три совета из упомянутой статьи:

Иметь меньше DOM.Это критически важная часть головоломки.Если элементы DOM не видны, вы должны удалить их из DOM, используя * ngIf вместо простого скрытия элементов с помощью CSS.Как говорится, самый быстрый код - это код, который не выполняется, а самый быстрый DOM - это DOM, который не существует.

Сделайте ваши выражения быстрее.Переместите сложные вычисления в хук жизненного цикла ngDoCheck и обратитесь к вычисленному значению в вашем представлении.Кэшируйте результаты в сложные вычисления как можно дольше.

Используйте стратегию обнаружения изменений OnPush, чтобы сообщить Angular 2, что изменений не было.Это позволяет вам пропустить весь этап обнаружения изменений в большинстве ваших приложений.

0 голосов
/ 06 июня 2018

ОК, я нашел решение своей проблемы, предварительно рассчитав состояние по всем полям на стороне компонента.Так что для профиля пользователя это моя функция:

 computesFieldsDisableState() {
    this.disabled = {
      thumbnails: !this.authService.hasPermission([this.permissions.profil.update], this.user.id, "user", "thumbnails"),
      name: !this.authService.hasPermission([this.permissions.profil.update], this.user.id, "user", "name"),
      firstname: !this.authService.hasPermission([this.permissions.profil.update], this.user.id, "user", "firstname"),
      password: !this.authService.hasPermission([this.permissions.profil.update], this.user.id, "user", "password"),
      email: !this.authService.hasPermission([this.permissions.profil.update], this.user.id, "user", "email"),
      roles: !this.authService.hasPermission([this.permissions.profil.update], this.user.id, "user", "roles"),
    };
  }

Теперь мне просто нужно использовать [disabled]="disabled.thumbnails", чтобы получить состояние поля.

Спасибо всем за ответы.

0 голосов
/ 06 июня 2018

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

Вот мои предложения:

  1. Используйте RxJS для отслеживания изменений,
    • Попробуйте обнаружить ваши permissions.applications.any.update изменения и включить их в Observable.Вы можете подписаться на это с помощью ngOnInit в вашем компоненте.
  2. Используйте Pure Pipe для обнаружения изменений.
    • Попробуйте перенести метод isDisabled на чистый компонент трубы.
  3. Используйте setInterval для периодической проверки изменений состояния.
...