如何在角度2中的星级评分插件中传递动态值?

时间:2017-04-04 13:11:01

标签: angular

我试图用浮点(4.3 / 5)显示开始。如果我给stars-selected="2.5"提供静态值,则代码下方工作正常。

如果我在角度2中给出stars-selected="{{CityList.rating}}"这样的动态值,那么它就无法正常工作。

我收到了错误。

  

未处理的Promise拒绝:模板解析错误:无法绑定到   '明星选择',因为它不是'明星'的已知属性。   (“yList.name}}

      

{{CityList.rating}}           ] stars-selected =“{{CityList.rating}}”disabled =“true”>

如何动态传递值?

list.components.ts

无效

<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

工作

<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;
    }
}

1 个答案:

答案 0 :(得分:1)

这应该有效:

<强> 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> 

或者,既然您可以更新软件包,只需使用Input而不是ElementRefngInit来初始化数据: 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;
}