Демо доступно здесь - https://stackblitz.com/edit/angular-a9wcee
Пожалуйста, откройте окно консоли, чтобы увидеть ошибку.
Описание
У меня есть Bootstrap
компонент ComponentA
, который должен запускаться двумя различными способами в зависимости от процесса запуска приложения. Скажем, если приложение запускается с помощью URL home.com
, тогда ComponentA
не должно отображать всплывающее диалоговое окно при запуске, но если приложение запускается с использованием home.com;signup
, приложение должно отображать всплывающее окно.
Я прочитал, что Input
не работает для компонентов начальной загрузки, поэтому я передаю атрибут ComponentA
из моего index.html
в качестве "контекста запуска".
<comp-a someAttr="someValue"></comp-a> <!--depending on whether someAttr is empty ("") or not, the pop should not be shown or shown respectively -->
и ComponentA
используют DialogComponent
в своем шаблоне следующим образом
<comp-dialog [message]=""></comp-dialog> <!-- I want the input to ComponentB to be empty to begin with -->
ComponentB
является диалоговым окном Bootstrap
css
и принимает сообщение Input
, которое отображается, когда диалоговое окно становится видимым. Сложность в том, что ComponentB
находится в шаблоне ComponentA
и, таким образом, Angular инициализирует его как часть запуска ComponentA
, но до того, как запуск ComponentA
завершен, ComponentA
пытается изменить ComponentB
(свойство message
), если оно определяет необходимость отображения диалогового окна (ComponentB
) (путем проверки атрибута). Я думаю, что это создает проблемы с Change Detection
, и я Angular
выдает ExpressionChangedAfterItHasBeenCheckedError
ошибку. Как я могу изменить дизайн взаимодействия компонентов
Фрагменты кода ComponentA
Проверьте, как меня начали.
ngAfterViewChecked(){
this.signup = this.el.nativeElement.getAttribute('signup'); //get the attribute
this.isSignupProcess();//check if ComponentB needs to be shown and update its message property
}
isSignupProcess(){
console.log("sign up is "+this.signup)
if(this.signup!==""){ //show ComponentB
if(this.signup === "success") {
this.showDialog("Signup was successful",new DialogContext("","")) //set message property of ComponentB
}else if(this.signup === "error") {
this.showDialog("Error: Signup wasn't successful",new DialogContext("",""))
} else {
this.showDialog("Unrecognised message: "+this.signup,new DialogContext("",""))
}
this.signup = ""; //no need to show ComponentB
} else {
}
}
логика для обновления message
свойства ComponentB
и показа
showDialog(message:string,context:DialogContext) {
this.dialogComponent.dialogShow(message,context);
}
ComponentB
просто вызывает Bootstrap
модальную функцию
dialogShow(message:string, context:DialogContext){
this.dialogContext = context;
this.dialogMessage = message;
console.log("dialog got context ",this.dialogContext);
$(this.dialogRef.nativeElement).modal('show');
}
html
из ComponentB
является
<div #modal class="modal fade" tabindex="-1" role="dialog" id={{dialogID}}>
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">CodingJedi</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="dialogHide()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>{{dialogMessage}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="dialogHide()">Close</button>
</div>
</div>
</div>
</div>