Reputation: 9341
I trying to display start with floating points (4.3/5). below the code is working fine if I give static value to stars-selected="2.5"
.
its not working if I give dynamic value like stars-selected="{{CityList.rating}}"
in angular 2.
I'm getting error.
Unhandled Promise rejection: Template parse errors: Can't bind to 'stars-selected' since it isn't a known property of 'stars'. ("yList.name}}
{{CityList.rating}} ]stars-selected="{{CityList.rating}}" disabled="true">
How to pass the values dynamically?
list.components.ts
Not working
<div *ngFor="let CityList of FoodList.categorylistvalues; let i = index; ">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 " >
<p>{{CityList.rating}}<stars stars="5" radius="8" stars-selected="{{CityList.rating}}" disabled="true"></stars></p>
</div>
</div>
list.components.ts
working
<div *ngFor="let CityList of FoodList.categorylistvalues; let i = index; ">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 " >
<p>{{CityList.rating}}<stars stars="5" radius="8" stars-selected="2.5" disabled="true"></stars></p>
</div>
</div>
star.component.ts
import {Component, ElementRef} from '@angular/core';
@Component({
selector: 'star-item',
inputs: ['radius', 'type', 'backColor'],
styles: [`
canvas.star {
float: left;
z-index: 1;
}
`],
template: `
<canvas
class="star"
height="{{ radius*2 }}"
width="{{ radius*2 }}"></canvas>`
})
export class StarItemComponent {
radius: number;
root: ElementRef;
backColor: string;
type: string;
constructor(myElement: ElementRef) {
this.root = myElement;
}
// Entry point for item drawing
drawItem(type: string, ctx: CanvasRenderingContext2D, r: number) {
return typeof this[type] === 'function' ? this[type](ctx, r) : this.star(ctx, r);
}
// Draw star image
star(ctx: CanvasRenderingContext2D, r: number) {
if (!ctx) throw Error('No Canvas context found!');
ctx.save();
ctx.globalCompositeOperation = 'destination-out';
ctx.beginPath();
ctx.translate(r, r);
ctx.moveTo(0, 0 - r);
for (var i = 0; i < 5; i++) {
ctx.rotate(Math.PI / 5);
ctx.lineTo(0, 0 - (r * 0.5));
ctx.rotate(Math.PI / 5);
ctx.lineTo(0, 0 - r);
}
ctx.fill();
ctx.restore();
}
// Draw circle image
circle(ctx: CanvasRenderingContext2D, r: number) {
if (!ctx) throw Error('No Canvas context found!');
ctx.save();
ctx.globalCompositeOperation = 'destination-out';
ctx.beginPath();
ctx.arc(r, r, r, 0, 2 * Math.PI, false);
ctx.fill();
ctx.restore();
}
// Draw main canvas area
drawRect(ctx: CanvasRenderingContext2D, dim: number, backColor: string) {
if (!ctx) throw Error('No Canvas context found!');
ctx.save();
ctx.fillStyle = backColor;
ctx.fillRect(0, 0, dim, dim);
ctx.restore();
}
// Hook: draw canvas image on the template rendered
ngOnInit() {
setTimeout(() => {
const el: HTMLCanvasElement = this.root.nativeElement.querySelector('.star');
const ctx: CanvasRenderingContext2D = el.getContext("2d");
this.drawRect(ctx, this.radius * 2, this.backColor);
this.drawItem(this.type, ctx, this.radius);
});
}
}
stars.component.ts
import {Component, ElementRef} from '@angular/core';
@Component({
selector: 'stars',
styles: [`
.stars {
display: inline-block;
position: relative;
z-index: 0;
}
.stars-selected {
position: absolute;
max-width: 100%;
height: 100%;
z-index: -1;
}
`],
template: `
<div class="stars"
[ngStyle]="{'background-color': starBackColor}"
(click)="secureNewRating()"
(mouseleave)="leaveRating()"
(mousemove)="changeRating($event)">
<div class="stars-selected"
[ngStyle]="{'width': selectedWidth, 'background-color': selectedColor}"></div>
<star-item *ngFor="let i of itemsIterable" [type]="type" [backColor]="backColor" [radius]="radius"></star-item>
</div>
`
})
export class StarComponent {
radius: number;
type: string;
items: number;
itemsIterable: number[];
selectedColor: string;
backColor: string;
starBackColor: string;
securedWidth: string;
selectedWidth: string;
percent: string;
starsSelected: number;
disabled: boolean;
el: ElementRef;
elDimensions: ClientRect;
starsSelectedNew: number;
constructor(el: ElementRef) {
const nativeEl = el.nativeElement;
const getAttr = (nEl: HTMLElement, attr: string, def?: string) :string => nEl.getAttribute(attr) || def;
// Pass attributes into app
this.selectedColor = getAttr(nativeEl, 'sel-color', '#e6a719');
this.backColor = getAttr(nativeEl, 'back-color', 'white');
this.starBackColor = getAttr(nativeEl, 'star-back-color', 'lightgray');
this.radius = parseInt(getAttr(nativeEl, 'radius', '30'), 10);
this.items = parseInt(getAttr(nativeEl, 'items', '5'), 10);
this.percent = getAttr(nativeEl, 'percent', '0') + '%';
this.starsSelected = parseFloat(getAttr(nativeEl, 'stars-selected', '0'));
this.starsSelectedNew= parseFloat(getAttr(nativeEl, 'starsSelectedNew', '0'));
//this.starsSelected = this.starsSelectedNew;
console.log(this.starsSelected);
this.disabled = !!getAttr(nativeEl, 'disabled');
this.type = getAttr(nativeEl, 'type', 'star');
this.itemsIterable = new Array(this.items);
this.securedWidth = this.starsSelected ? 100 / this.items * this.starsSelected + '%' : this.percent;
this.elDimensions = nativeEl.getBoundingClientRect();
this.el = el;
// initial rating setup
this.selectedWidth = this.securedWidth;
}
changeRating(e: MouseEvent) {
this.selectedWidth = !this.disabled && e.clientX - this.elDimensions.left + 'px';
this.percent = parseInt(this.selectedWidth, 10) / this.radius * 2 * this.items + '%';
}
leaveRating() {
this.selectedWidth = this.securedWidth;
}
secureNewRating() {
this.securedWidth = this.percent;
}
}
Upvotes: 0
Views: 3740
Reputation: 2317
This should work :
list.component.html
<div *ngFor="let CityList of FoodList.categorylistvalues; let i = index; ">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 " >
<p>{{CityList.rating}}<stars stars="5" radius="8" [attr.stars-selected]="CityList.rating" disabled="true"></stars></p>
</div>
</div>
Or, since you can update the package, just use Input
s instead of ElementRef
and ngInit
to init the data : Plunker
@Input('radius') radius: number = 30;
@Input('type') type: string = 'star';
@Input('items') items: number = 5;
@Input('sel-color') selectedColor: string = '#e6a719';
@Input('back-color') backColor: string = 'white';
@Input('star-back-color') starBackColor: string = 'lightgray';
@Input('percent') percent: string = '0';
@Input('stars-selected') starsSelected: number = 0;
@Input('disabled') disabled: boolean = false;
securedWidth: string;
selectedWidth: string;
itemsIterable: number[];
constructor() {
}
ngOnInit() {
// Pass attributes into app
this.percent += '%';
this.itemsIterable = new Array(this.items);
this.securedWidth = this.starsSelected ? 100 / this.items * this.starsSelected + '%' : this.percent;
// initial rating setup
this.selectedWidth = this.securedWidth;
}
Upvotes: 1