Ошибка "Can't bind to 'ngFor' since it isn't a known native property" в Angular
Список пользователей
- {{ user.name }}
Проблема: отсутствие CommonModule в модуле компонента
Основная причина этой ошибки — Angular не может найти директиву *ngFor в текущем модуле. Хотя вы импортировали BrowserModule в корневой модуль, для использования *ngFor и других структурных директив (*ngIf, *ngSwitch) необходимо импортировать CommonModule в каждый модуль, где используются эти директивы.
CommonModule содержит все основные директивы Angular, включая NgFor, NgIf, NgSwitch, а также пайпы (DatePipe, UpperCasePipe и др.) и другие базовые возможности.
Решение: импортируйте CommonModule
Вам нужно добавить CommonModule в массив imports вашего модуля. Вот исправленный код:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { AppComponent } from './app.component';
import { UserListComponent } from './user-list.component';
@NgModule({
declarations: [
AppComponent,
UserListComponent
],
imports: [
BrowserModule,
CommonModule // <-- Добавьте эту строку
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Если ваш компонент находится в отдельном модуле (например, UserModule), импортируйте CommonModule именно туда:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { UserListComponent } from './user-list.component';
@NgModule({
declarations: [UserListComponent],
imports: [CommonModule], // <-- Обязательно!
exports: [UserListComponent]
})
export class UserModule { }
Почему это работает?
- BrowserModule — экспортирует
CommonModule, но только для корневого модуля приложения. Он предназначен для однократного импорта вAppModule. - CommonModule — это модуль, который содержит все основные директивы Angular. Его нужно импортировать в каждый функциональный модуль, где используются эти директивы.
- Angular использует модульную систему: каждый модуль изолирован, и директивы из одного модуля не видны в другом без явного импорта.
Дополнительные советы
1. Проверьте версию Angular. В очень старых версиях (Angular 2 beta) *ngFor назывался *ng-for, но в современных версиях (2+) используется *ngFor.
2. Используйте трек-функцию для оптимизации производительности при работе с большими списками:
trackByUser(index: number, user: any): number {
return user.id; // или любой уникальный идентификатор
}
И в шаблоне:
<li *ngFor="let user of users; trackBy: trackByUser">{{ user.name }}</li>
3. Помните о синтаксисе. Звёздочка (*) перед ngFor — это синтаксический сахар для использования шаблонов. Без неё нужно писать:
<ng-template ngFor let-user [ngForOf]="users">
<li>{{ user.name }}</li>
</ng-template>
Но вариант со звёздочкой проще и читаемее.
После добавления CommonModule ошибка должна исчезнуть, и ваш список пользователей будет корректно отображаться.
Альтернативный подход: использование standalone компонентов
Начиная с Angular 14, вы можете использовать standalone компоненты, которые не требуют объявления в модуле. Это упрощает структуру приложения и избавляет от необходимости импортировать CommonModule вручную.
Вот как переписать ваш компонент с использованием standalone подхода:
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-user-list',
standalone: true, // <-- Указываем, что компонент standalone
imports: [CommonModule], // <-- Импортируем CommonModule напрямую
template: `
<div>
<h2>Список пользователей</h2>
<ul>
<li *ngFor="let user of users">{{ user.name }}</li>
</ul>
</div>
`
})
export class UserListComponent {
users = [
{ name: 'Иван', age: 25 },
{ name: 'Мария', age: 30 },
{ name: 'Петр', age: 28 }
];
}
Теперь вам не нужно добавлять компонент в declarations или imports модуля. Просто импортируйте его туда, где используете:
import { bootstrapApplication } from '@angular/platform-browser';
import { UserListComponent } from './user-list.component';
bootstrapApplication(UserListComponent);
Этот подход особенно удобен для небольших приложений или при миграции с более старых версий Angular. Он делает код более модульным и уменьшает количество boilerplate кода.
Обратите внимание: если вы используете Angular 14 и выше, standalone компоненты — это рекомендуемый способ разработки новых приложений.