0

I am new to angular and I am trying to manipulate an instance of a component's html template based on that instance's input data. I want to take an integer value and produce the same number of stars (as the html entity &#9733) as you would see in a star rating system. I have a parent component "RatingList" that dynamically produces a "RatingCard" which contains the star rating (see photo for example). I am able to dynamically create the "RatingCard" and during ngAfterViewInit, I am trying to create the star rating. I access the element where I want to put the stars by using selectRootElement but it seems to only grab the first instance of a "RatingCard" and then adds all subsequent instances to the star ratings of that instance.

I am wondering what is the proper way to find a specific html tag in an instance of a RatingCard and then update it. I have tried declaring a variable using ViewChild but that does not seem to work. I am also wondering how to properly insert the html entity for a star. Thank you for considering this!

I've removed some code for clarity.

rating-list.component.ts

import {Component, Input, OnInit, ComponentFactoryResolver, OnDestroy, ViewContainerRef, Type} from "@angular/core";
import { RatingCardComponent} from "../rating-card/rating-card.component"

let titles = ["Road to Perdition", "Cool Hand Luke"]
let ratings =  [7, 4];
@Component({
  selector: 'app-rating-list',
  template: '<ng-template appRatingHost></ng-template>'
})
export class RatingListComponent implements OnInit {

  constructor(private vf:ViewContainerRef, private componentFactoryResolver : ComponentFactoryResolver) {}

  ngOnInit(): void {
    this.loadComponents();
  }

  loadComponents() {

    for (let index = 0; index < 2; index++) {
      const componentFactory = 
 this.componentFactoryResolver.resolveComponentFactory(RatingCardComponent);

      const componentRef = this.vf.createComponent<RatingCardComponent>(componentFactory);

      const data = {imgUrl : urls[index], title : titles[index], rating : ratings[index]};

      componentRef.instance.data = data;
      
    }
  }

rating-card.component.ts


import { Component, ElementRef, OnInit, Renderer2, ViewChild } from '@angular/core';


@Component({
  selector: 'app-rating-card',
  templateUrl: './rating-card.component.html',
  styleUrls: ['./rating-card.component.css']
})
export class RatingCardComponent implements OnInit {

  data : any;

  @ViewChild('#rating-header') rating_header? : ElementRef;

  constructor(private renderer : Renderer2, private el : ElementRef) { }



  ngOnInit(): void {
      
  }

  ngAfterViewInit()
  {
    this.setupRating(this.data.rating)
  }



  setupRating(size : Number) : void {
    for (let index = 0; index < size; index++) {
      let starContainer = this.renderer.createElement('span');
      let text = this.renderer.createText("&#9734;");
      
      this.renderer.addClass(starContainer, 'gold_full_star');
     
      this.renderer.appendChild(starContainer, text);

      const rating_header = this.renderer.selectRootElement("#rating-header", true);

      this.renderer.appendChild(rating_header, starContainer);
    }
  }

}

rating-card.component.html


<div class="card" tabindex="0">
        <img class="movieimg" height=96x width=96px alt="" src={{data.imgUrl}}/>
        <h3 class="card-title">{{data.title}}</h3>
        <h4 class="card-subtitle" id="rating-header">Rating:{{data.rating}}</h4>
        <p class="card-text">This is where I write my review ... ?</p>
    </div>

Image of what is currently displayed

1 Answer 1

3

why don´t you just create a star-rating.component and do the stars with an *ngFor loop using angular syntax instead of messing around with underlying dom structure?

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.