Почему стоит использовать protected в Angular компонентах?
Если вы используете в своих компонентах только public и private, вы упускаете возможность сделать архитектуру чище. Я предлагаю четко разделять ответственность членов класса.
Часто мы по инерции делаем public любые методы и свойства, которые нужны в шаблоне (HTML). Но public в TypeScript означает, что это публичный API компонента - к этим методам может получить доступ любой родительский компонент через @ViewChild.
Почему стоит использовать protected:
1. Явное намерение: protected сигнализирует, что метод предназначен для использования внутри класса или в его шаблоне, но не должен вызываться извне.
2. Защита от регрессии: Если другой разработчик попытается вызвать такой метод через @ViewChild, TypeScript выдаст ошибку. Это заставит его задуматься: «Действительно ли мне нужно делать этот метод публичным?» или «Может, стоит создать отдельный метод для API?».
3. Читаемость: Открывая код, вы сразу видите: public - для внешнего мира, protected - для шаблона, private - для внутренней логики сервисов и подписок.
Разделяйте Public API и внутреннюю логику шаблона - ваш код станет надежнее и понятнее.
@Component({ selector: 'app-user-profile', template: ` <!-- В шаблоне мы без проблем обращаемся к protected свойствам --> <div class="card"> <h3>{{ userName() }}</h3> <button (click)="onUpdateClick()">Обновить</button> @if(isLoading()) { <div>Загрузка...</div> } </div> ` }) export class UserProfileComponent { // PRIVATE: Внутренняя логика. // Не доступно ни в шаблоне, ни родительскому компоненту. private _userId = 123; // PROTECTED: Доступно только внутри класса и в ШАБЛОНЕ. // Идеально для переменных состояния UI и обработчиков событий. protected userName = signal('Алексей'); protected isLoading = signal(false); protected onUpdateClick(): void { this.logAction(); console.log('Кнопку нажали в шаблоне'); } // PUBLIC: Публичный API компонента. // Только эти методы мы разрешаем вызывать родительскому компоненту. public resetState(): void { this.userName.set('Гость'); this.isLoading.set(false); } private logAction(): void { console.log(`Action logged for userId: ${this._userId}`); } }
