简体   繁体   中英

Angular does not rerender on Input() change

Whatever i do angular does not detect change on talks array. I have a handleSubmit function to send the toolbar. Toolbar use it to send the changes to parent from input field.

My app.component.ts file

import { Component, Type, OnChanges, SimpleChanges } from '@angular/core';
import { getResponse } from '../api/API';

declare module '../api/API' {
  export interface NlpAPI {
    getResponse(data: any): Promise<any>;
  }
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnChanges {
  talks: string[];
  title: string;
  ngOnChanges(changes: SimpleChanges): void {
    console.log(changes);
  }
  constructor() {
    this.talks = [];
    this.title = 'Talks';
  }
  ngOnInit() {
    this.talks.push('Welcome to ProjectX! How can I help you?');
    this.talks.push('I am a chatbot. I can help you with your queries.');
  }
  handleSubmit(data: any): void {
    this.talks.push(data.talk);
  }
  messageResponse() {
    // @ts-ignore: Object is possibly 'null'.
    const x = document.getElementById('txt').value;
    // @ts-ignore: Object is possibly 'null'.
    document.getElementById('output').innerHTML =
      'Your message is ' + '"' + x + '"';
  }
}

My app.component.html

<!-- Toolbar -->
<app-custom-toolbar [handleSubmit]="handleSubmit"></app-custom-toolbar>

<!-- Highlight Card -->

<app-text-area [talksFromUser]="talks" [title]="title"></app-text-area>
<!-- Bottombar -->
<router-outlet></router-outlet>

My text-area.component.ts file

import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';

@Component({
  selector: 'app-text-area',
  templateUrl: './text-area.component.html',
  styleUrls: ['./text-area.component.css'],
})
export class TextAreaComponent implements OnChanges {
  @Input() talksFromUser: string[] = [];
  @Input() title: string = '';
  constructor() {}
  ngOnChanges(changes: SimpleChanges): void {
    console.log(changes);
  }
}

My text-area.component.html

<div class="main-text-area">
  <div *ngFor="let item of talksFromUser">{{ item }}</div>
</div>

custom-toolbar.component.ts file

import { Component, Input, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';

@Component({
  selector: 'app-custom-toolbar',
  templateUrl: './custom-toolbar.component.html',
  styleUrls: ['./custom-toolbar.component.css'],
})
export class CustomToolbarComponent implements OnInit {
  talks: string[] = [];
  @Input() handleSubmit!: (args: any) => void;
  constructor() {}
  ngOnInit(): void {}
  onSubmit(f: NgForm) {
    this.handleSubmit(f.value);
    f.resetForm();
  }
}

I tried also this.talks = [...this.talks, data.talk] Thank you all.

There are two issues in your code:

  • First one, you are calling handleSubmit("string") (so data is a string), but you are pushing data.talk , which is undefined (so talks will be [undefined, undefined, ...] ). To fix it, use data :
handleSubmit(data: any): void {
    this.talks.push(data); // use "data" instead of "data.talk"
}
  • Second one, you are using a AppComponent method into CustomToolbarComponent class. You need to keep the this scope of AppComponent . Also, you should use arrow functions:
handleSubmit = (data: any): void => {
    this.talks.push(data);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM