Hello I have component for chat messages. I have a problem with change detection. When I typed, ngFor directive still redraws all messages. I would like to draw messages when I displayed this component and then after I added new message. Here is my code:
chat.component.ts:
@Component({
selector: 'my-chat',
templateUrl: './chat.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChatComponent implements OnInit {
text: string;
@Input() messages: ChatMessage[];
@Output() onChanged: EventEmitter<string> = new EventEmitter<string>();
constructor(private app: App, private cd: ChangeDetectorRef) {}
ngOnInit() {
this.messages = !this.messages ? [] : this.messages;
}
onChangeHandler(value: string) {
this.onChanged.emit(value);
}
trackByFn(index, item){
console.log(index, item); //still calls when typing
return item.Id;
}
}
export interface ChatMessage {
Text: string;
}
chat.component.html:
<form action="#" method="post" *ngIf="!readonly" [style.margin-bottom]="'10px'">
<div class="img-push" [ngClass]="{'input-group': enableSaveButton}">
<textarea class="form-control input-sm" rows="2" style="resize:none" [(ngModel)]="text" [ngModelOptions]="{standalone: true}"
(ngModelChange)="onChangeHandler($event)"></textarea>
</div>
</form>
<div class="box-body box-comments pre-scrollable">
<ng-container *ngIf="messages.length != 0">
<div class="box-comment" *ngFor="let message of messages; let i=index;trackBy:trackByFn">
<div class="comment-text">
<pre>{{message.Text}}</pre>
</div>
</div>
</ng-container>
</div>

<my-chat [messages]="data.Messages" (onChanged)="hasChanges($event)" *ngIf="data.Messages"/>data.Messagesvariable.*ngIf="data.Messages"is probably making your component visible even if it is[]. You probably want to formulate a different condition to make your component visible. If you want to not display this component until user actually enters a new message, then you will have to compare the lengths of themessagearray. Basically, you have to make your component visible at accurate event.