自定义选择组件的Angular2变换模型

自定义选择组件的Angular2变换模型,angular,components,ngmodel,Angular,Components,Ngmodel,在我的angular2应用程序中,我希望有一个可重用的select组件,在初稿中,该组件如下所示: import {Component, Input, Output, EventEmitter} from "@angular/core"; @Component({ selector: 'my-select', template: ` <select [(ngModel)]="selectedValue" (ngModelChange)="selectionC

在我的angular2应用程序中,我希望有一个可重用的select组件,在初稿中,该组件如下所示:

import {Component, Input, Output, EventEmitter} from "@angular/core";
@Component({
    selector: 'my-select',
    template: `
        <select [(ngModel)]="selectedValue" (ngModelChange)="selectionChanged()">
            <option disabled="disabled" selected="selected" name="choose" value="choose">choose ...</option>
            <option *ngFor="let opt of selectModel" [ngValue]="opt">
                {{opt}}
            </option>
        </select>
    `
})
export class SelectComponent {

    @Output()
    changed: EventEmitter<any> = new EventEmitter();

    @Input()
    selectModel: any[] = [];

    selectedValue: any = 'choose';

    selectionChanged() {
        this.changed.emit(this.selectedValue);
    }
}
import {Component} from "@angular/core";

export class Foo {
    bar: string;
    id: number;
    userFriendlyString: string = `id=${this.id}|bar=${this.bar}`;

    constructor(bar: string, id: number) {
        this.bar = bar;
        this.id = id;
    }
}

@Component({
    template: `<my-select [selectModel]="model" (changed)="handle($event)"></my-select>`
})
export class AppComponent {
    model: Foo[] = [new Foo('first', 1), new Foo('second', 2)];
    handle(foo: Foo): void {/* ... */}
}
将仅打印出其他类型的[Object]。因此,EventEmitter只会发出字符串。 现在,我想要的是一个组件,我可以像这样使用它:

import {Component, Input, Output, EventEmitter} from "@angular/core";
@Component({
    selector: 'my-select',
    template: `
        <select [(ngModel)]="selectedValue" (ngModelChange)="selectionChanged()">
            <option disabled="disabled" selected="selected" name="choose" value="choose">choose ...</option>
            <option *ngFor="let opt of selectModel" [ngValue]="opt">
                {{opt}}
            </option>
        </select>
    `
})
export class SelectComponent {

    @Output()
    changed: EventEmitter<any> = new EventEmitter();

    @Input()
    selectModel: any[] = [];

    selectedValue: any = 'choose';

    selectionChanged() {
        this.changed.emit(this.selectedValue);
    }
}
import {Component} from "@angular/core";

export class Foo {
    bar: string;
    id: number;
    userFriendlyString: string = `id=${this.id}|bar=${this.bar}`;

    constructor(bar: string, id: number) {
        this.bar = bar;
        this.id = id;
    }
}

@Component({
    template: `<my-select [selectModel]="model" (changed)="handle($event)"></my-select>`
})
export class AppComponent {
    model: Foo[] = [new Foo('first', 1), new Foo('second', 2)];
    handle(foo: Foo): void {/* ... */}
}
我的意图:

告诉myselect组件,显示的值应该是Foo的userFriendlyString属性。我不想硬编码,因为其他组件应该能够将我的select与其他模型类一起使用。我无法想象怎么做。我的第一种方法是使用回调函数作为我的select组件的@Input,但这不起作用,也不应该这样做。第二种方法是在Foo中重写toString。也不起作用,我假设在任何…?!中缺少动态调度。。。?!。 让EventEmitter按“预期”工作:在句柄函数中应该有一个正确的foo:foo。
那么,我还有希望吗

我想我要做的是创建一个组件可以将其对象映射到的公共接口,例如:

export interface SelectListObject{
    key: string;
    value: any;
}
然后将其用作选择列表组件的输入类型:

@Component({
    selector: 'my-select',
    template: `
        <select [(ngModel)]="selectedValue" (ngModelChange)="selectionChanged()">
            <option disabled="disabled" selected="selected" name="choose" value="choose">choose ...</option>
            <option *ngFor="let opt of selectModel" [ngValue]="opt.value">
                {{opt.key}}
            </option>
        </select>
    `
})
export class SelectComponent {

    @Output()
    changed: EventEmitter<any> = new EventEmitter();

    @Input()
    selectModel: SelectListObject[] = [];

    selectedValue: any = 'choose';

    selectionChanged() {
        this.changed.emit(this.selectedValue);
    }
}
handle函数对于使用SelectComponent的每个组件都是唯一的,因此该值可以是您需要输入的任何类型


希望对您有所帮助。

您是否可以执行类似操作,使用$event,以便返回值和您想要的任何内容,并将输入设置为获取具有显示和值的对象数组-

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

interface selectModel {
    display: string;
    value: any;
}

@Component({
selector: 'my-select',
template: `
    <select [(ngModel)]="selectedValue" (ngModelChange)="selectionChanged($event)">
        <option disabled="disabled" selected="selected" name="choose" value="choose">choose ...</option>
        <option *ngFor="let opt of selectModel" [ngValue]="opt.value">
            {{opt.display}}
        </option>
    </select>
`
})
    export class SelectComponent {

    @Output()
    changed: EventEmitter<any> = new EventEmitter();

    @Input()
    selectModel: selectModel[];

    selectedValue: any = 'choose';

    selectionChanged(event) {
        let response = {
            value: event.target.value,
            foo: "something else"
        }
        this.changed.emit(response);
    }
}

工作起来很有魅力:我也有这样的想法,但是界面的两个部分,键和值是缺少的东西,就像上面一样。。。但是我喜欢输入和输出的通用界面,我想我在他之后2分钟回答说:很高兴你解决了你的问题。