Home > Net >  Why doesn't angular render my field component?
Why doesn't angular render my field component?

Time:11-25

I have a BoxComponent that has only one field, an array of numbers. The selector for this Component is app-box

box.component.html

<p>
    <span *ngFor="let num of cards">Number is {{num}}</span>
</p>

box.component.ts

export class BoxComponent {

  cards: number[] = [];

  top_up(val: number) {
    this.cards.push(val);
  }

}

In its parent AppComponent, I added a single field that stores a BoxComponent object.

app.component.html

<app-box></app-box>
<button (click)="push()">Top-up</button>

app.component.ts

export class AppComponent {
  title = 'test';
  box: BoxComponent = new BoxComponent();

  push() {
    this.box.top_up(Math.floor(Math.random() * 10));
  }
}

I wish to make the click in the appcomponent template to modify the contents of app-box. However angular does not update the app-box when the button is clicked. I somehow was able to confirm that the field box of appcomponent actually gets updated, the change just doesn't show in the browser. Based on this I have concluded that the app-box tag creates a different BoxComponent rather than use the one I have created within the AppComponent class.

Am I right? How do I make angular render my box and respond to changes I make to it from the AppComponent click event?

Edit: I have simplified the problem to its simplest form.

CodePudding user response:

change the app component to :

export class AppComponent {
  title = 'test';
  @ViewChild('bComponent') boxComponent!: BoxComponent;

  push() {
    this.boxComponent.top_up(Math.floor(Math.random() * 10));
  }
}

and it's html to :

<app-box #bComponent></app-box>
<button (click)="push()">Top-up</button>

CodePudding user response:

Just add the "return" keyword in the "add_card" function.

card.ts

export class Card {
  suit: number | undefined;
  rank: number | undefined;

  constructor(suit: number, rank: number) {
    this.suit = suit;
    this.rank = rank;
  }
}

player.component.ts

import { Component } from '@angular/core';
import { Card } from '../card';

@Component({
  selector: 'app-player',
  templateUrl: './player.component.html',
  styleUrls: ['./player.component.css'],
})
export class PlayerComponent {
  cards: Card[] = [];

  constructor() {
    this.cards = [new Card(2, 4), new Card(3, 7)];
  }

  add_card() {
   return this.cards.push(new Card(2, 4));
  }
}

player.component.html

<div >
    <ng-content></ng-content>
    <div >
        <div  *ngFor="let card of cards">
            <span>suit {{card.suit}}</span>
            <span>rank {{card.rank}}</span>
        </div>
    </div>
    <button (click)="add_card()">Add</button>
</div>

CodePudding user response:

Use this way in your App component

@ViewChild(BoxComponent)BoxComponentRef:BoxComponent;
push()
{
this.BoxComponentRef.top_up(Math.floor(Math.random());
}
  • Related