3
votes

The Logic by IMG I need child component variable to update real-time. I tried by @Input but its only initialized and dont changed over time.

Parent Component

<div>
    <h4>Рэйтынг : {{video.starRating}}</h4>
    <star-rating 
        [rating]="video.starRating" 
        (ratingChanged)="onRatingChanged($event)">
    </star-rating>
</div>

Child Component

   @Component({
        selector: 'star-rating',
        templateUrl: 'app/shared/star-rating.component.html',
        styleUrls:['app/shared/star-rating.component.css'],
        inputs:['rating']
   })
   export class StarRatingComponent implements OnInit,OnChanges {

     rating: number;
     @Output() ratingChanged = new EventEmitter<number>();

     ngOnChanges(changes: {[propKey: string]: SimpleChange}) {

        for (let propName in changes) {
            let changedProp = changes[propName];
           if(changedProp == "rating"){
               this.calcStarRating();
               console.log("rating = "+this.rating);
               console.log("ratingCurr = "+changedProp.currentValue);
               console.log("ratingPrev = "+changedProp.previousValue);
           }
        }
    }

    onStarClicked(item: number) {
        this.ratingChanged.emit(item + 1);
    }

    calcStarRating() {
        ...calc logic....
        console.log(this.rating)
    }

    ngOnInit() {
        this.calcStarRating();
    }
  }

The video is

export class Video{
    videoId:string;
    videoTitle:string;
    price: number;
    description: string;
    starRating: number;
    imageUrl: string;
}

Parent Logic

  export class VideoDetailComponent implements OnInit ,OnDestroy{

    video:Video;

    private sub: Subscription;

    ngOnInit() {
        this.sub = this._routeParams.params.subscribe(params=>{
            if(params && params['id']){
                this.sub1 =  this._vs.getItemById(params['id'])
                    .subscribe(t=>this.video = t);
            }
        });
    }

    onRatingChanged(rating:number){
        if(this.video.starRating!=0){
            this.video.starRating +=rating;
            this.video.starRating /= 2;
        }
        else this.video.starRating = rating;

        this.video.starRating = +this.video.starRating.toFixed(2);
        this._vs.updateItem(this.video);
    }

    onBack(){
        this.router.navigate(['/list']);
    }


    constructor(private _routeParams: ActivatedRoute,
                private _vs:VideoService,
                private router: Router) {

    }
  }

I logged rating and nothing is happen. I increment\decrement value. The parent model changed, but changes arent send to child by @input. The Question is how bind in real-time.Is it possible with @Input or i need use some Observable/Events e.t.c

Thanks for Reading:)

1
What is video and video.starRating?. What is onRatingChanged(). Where and when exactly do you expect the input to be updating? - Günter Zöchbauer
I have Model Detail. There are StarRating like 4.5, and down i have the stars. there are 4.5 of star. When i clicked for example 1 star, the event is going to up. The model changed to 3.blablalba. I see The rating is 3.124 for example but the rating on child is the same 4.5 - Hienadź Budkoŭski
It would be great if you could properly format your code. Currently it's a mess and hard to read. (inconsistent indentation, redundant empty lines). - Günter Zöchbauer
That looks much better :) - Günter Zöchbauer
I think problem is with if(changedProp == "rating"){...} line. change it to if(propName == "rating"){...}. check and let me know. - Nikhil Shah

1 Answers

1
votes

It works but seems like you have problem with if(changedProp == "rating"){...} line as your are matching/comparing object with string.

You need to change it to if(propName == "rating"){...}.

This will solve the problem.