Angular, когда я могу использовать переменные ссылок на шаблоны в директивах angular? - PullRequest
0 голосов
/ 15 апреля 2020

Я новичок в angular и у меня есть это сомнение. У меня очень странное поведение, используя следующий код:

<select #selectColor class="btn btn-primary" name="button">
  <option [value]="color" *ngFor="let color of COLORS">{{color}}</option>
</select>

<p customDirective [ngStyle]="{'color':selectColor.value}">
  Test paragraph
</p>

Этот код показывает следующую ошибку в консоли браузера, и она не работает:

ExpressionChangedAfterItHasBeenCheckedError: Выражение изменилось после его проверки. Предыдущее значение: 'color:'. Текущее значение: 'color: yellow'.

Но это "работает" и меняет цвет, когда я нахожу курсор мыши на элемент, потому что customDirective определил следующие методы:

@HostListener('mouseenter') mouseEnter(){
    //Some code
}

@HostListener('mouseleave') mouseLeave(){
    //Some code
}

Я загружаю демо по адресу: https://angular-zxhhml.stackblitz.io

Спасибо.

Ответы [ 2 ]

0 голосов
/ 15 апреля 2020

При создании компонента / директивы Angular выполняет набор методов, известных как ловушка жизненного цикла. Этот механизм описан здесь:

https://angular.io/guide/lifecycle-hooks

Проблема в том, что все методы этого жизненного цикла выполняются в один и тот же ход javascript vm и когда вы выбираете создается первое значение (здесь желтый) и вызывает эту ошибку.

Решение, как сказано в предыдущем ответе, заключается в использовании ngModel для отслеживания выбранного цвета. Чтобы выбрать первый цвет по умолчанию, я использую функцию setTimeout, которая позволяет отложить выполнение на следующий javascript vm ход и избежать предыдущей ошибки.

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit {
  name = 'Angular';
  COLORS = ['yellow', 'red', 'blue'];
  selectedColor: string;

  ngAfterViewInit(): void {
    setTimeout(() => {
      this.selectedColor = this.COLORS[0];
    });    
  }
}

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

@Directive({
  selector: '[customDirective]'
})
export class CustomDirectiveDirective {

  @Input() color: string;

  constructor(private readonly element: ElementRef) { }

  @HostListener('mouseenter') mouseEnter(){
    // Some code
  }

  @HostListener('mouseleave') mouseLeave(){
    // Some code
  }

}

Вот пример использования стекаблиц: https://stackblitz.com/edit/angular-ssq5af

0 голосов
/ 15 апреля 2020

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

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

компонент. html

<select class="btn btn-primary" name="button" #selectColor (change)="0">
  <option [value]="color" *ngFor="let color of COLORS">{{color}}</option>
</select>

<p customDirective [ngStyle]="{'color':selectedColor}">
  Test paragraph
</p>

Конечно, более стандартный (на мой взгляд) - и более простой - способ сделать это с привязкой свойства.

[(ngModel)]="selectedColor", а затем связать до selectedColor. Никаких свойств в компоненте строго не требуется, хотя я бы порекомендовал добавить их для ясности.

DEMO: https://stackblitz.com/edit/angular-lz1cae

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