Angular:为什么我的OutPut()装饰器不会将事件从嵌套组件引发到容器组件?

时间:2017-09-25 23:46:32

标签: angular events

我正在从头开始学习Angular。这个主题非常初学者,如果问题是基本的,请原谅我。 我正在学习嵌套组件如何通过使用Output()装饰器引发事件将数据发送到容器组件。 Start组件是名为product list component的容器组件内的嵌套组件。 当用户点击任何评级星时,容器组件的标题应该更改。 但似乎事件不是从星组件(嵌套组件)引发到产品列表组件(容器组件)。 这是我的代码:

star.component.html:

<div class="crop" 
[style.width.px]="starWidth"
[title]="rating"
(click)="onClick()">
<div style="width: 86px" >
    <span class="glyphicon glyphicon-star"></span>
    <span class="glyphicon glyphicon-star"></span>
    <span class="glyphicon glyphicon-star"></span>
    <span class="glyphicon glyphicon-star"></span>
    <span class="glyphicon glyphicon-star"></span>
</div>

star.component.ts

import { Component, OnChanges, SimpleChanges, Input, EventEmitter, Output } from "@angular/core";


@Component({
    selector: 'pm-start',
    templateUrl: './star.component.html',
    styleUrls: ['./star.component.css']
})

export class StarComponent implements OnChanges {
    @Input() rating: number;
    starWidth : number;    
    @Output() ratingClicked: EventEmitter<string> = new EventEmitter<string>(); 

    ngOnChanges(changes: SimpleChanges): void {
        this.starWidth = this.rating * 86/5;
    }


    onClick():void{
        console.log("stars are clicked");
        this.ratingClicked.emit(`The rating ${this.rating} was clicked`);
    }
}

product_list.component.html

<div class='panel panel-primary'>
    <div class='panel-heading'>
        {{pageTitle}}
    </div>
    <div class='panel-body'>
        <div class='row'>
            <div class='cpl-md-2'>Filter by:</div>
            <div class='col-md-4'>
                <input type="text" [(ngModel)] = 'listFilter' />
            </div>
        </div>
        <div class='row'>
            <div class='col-md-6'>
                <h3> Filter By: {{listFilter}}</h3>
            </div>
        </div>
        <div class='table-responsive'>
            <table class='table' *ngIf='products && products.length'>
                <thead>
                    <tr class="firstRow">
                        <th>
                            <button class='btn btn-primary'
                            (click) = 'toggleImage()'>
                                {{imageShow ? 'Hide' : 'Show'}}  Image
                            </button>
                        </th>
                        <th>
                            Product
                        </th>
                        <th>
                            Code
                        </th>
                        <th>
                            Available
                        </th>
                        <th>
                             Price
                        </th>
                        <th>
                         5 Start Rating
                        </th>
                    </tr>

                </thead>
                <tbody>
                        <tr *ngFor='let product of filteredProducts'>
                                <td><img
                                    *ngIf = 'imageShow'
                                    [src]='product.imageUrl' [title]='product.productName' 
                                    [style.width.px] = 'imageWith' [style.height.px] = 'imageHeight'></td>
                                <td>{{product.productName}}</td>
                                <td>{{product.productCode | lowercase | covertToSpaces:'-'}}</td>                        
                                <td>{{product.releaseDate}}</td>
                                <td>{{product.price | currency:'USD': true :'1.2-2'}}</td>
                                <td><pm-start [rating]='product.starRating' (ratingClikced)='onRatingClicked($event)'></pm-start></td>
                            </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

product_list.component.ts

import {Component} from "@angular/core"
import { IProduct } from "./product";


@Component({
    selector: 'pm-products',    
    templateUrl: './product-list.component.html',
    styleUrls:['./product-list.component.css'],

})

export class ProductListComponent{
    pageTitle: string = 'Product List' ;
    imageWith: number = 40;
    imageHeight: number = 40;
    imageShow : boolean = false;
    _listFilter : string ;
    get listFilter():string {
        return this._listFilter;
    }
    set listFilter(value:string) {
        this._listFilter = value;
        this.filteredProducts = this._listFilter ? this.performFilter (this._listFilter) : this.products;
    }

    filteredProducts :IProduct[];
    products: IProduct[] = [
        {
            "productId": 1,
            "productName": "Leaf Rake",
            "productCode": "GDN-0011",
            "releaseDate": "March 19, 2016",
            "description": "Leaf rake with 48-inch wooden handle.",
            "price": 19.95,
            "starRating": 3.2,
            "imageUrl": "http://openclipart.org/image/300px/svg_to_png/26215/Anonymous_Leaf_Rake.png"
        },
        {
            "productId": 2,
            "productName": "Garden Cart",
            "productCode": "GDN-0023",
            "releaseDate": "March 18, 2016",
            "description": "15 gallon capacity rolling garden cart",
            "price": 32.99,
            "starRating": 4.2,
            "imageUrl": "http://openclipart.org/image/300px/svg_to_png/58471/garden_cart.png"
        }
    ];

    constructor(){
        this.filteredProducts = this.products;
        this._listFilter = 'cart'; 
    }

    onRatingClicked(someValue:string):void{
        console.log("some body passed data form");
        this.pageTitle = "Product List " + someValue;
    }

    toggleImage ():void{
        this.imageShow = !this.imageShow; 
    };

    performFilter (filter:string){
        //
        filter = filter.toLocaleLowerCase();
        return (this.products.filter((product:IProduct) => product.productName.toLocaleLowerCase().indexOf(filter) != -1));
    }

}

0 个答案:

没有答案