2017-10-18 8 views
0

내부 구성 요소의 수가 다른 여러 위치에서 사용되는 필터 구성 요소를 만들고 싶습니다.HTML 템플릿에 선언 된 구성 요소를 가져 오는 중

filter.component.html

<select-filter name="somename" ></select-filter> 
<input-filter name="somename"></input-filter> 
... 

선택 필터 및 입력 필터 인터페이스 FilterItem이

export interface FilterItem{ 
    name: string; 
    getValue() : any; 
} 

내가 각 구성 요소의 인스턴스를 얻으려면 구현하는 구성 요소 (예를 들어) (getValue를 호출) inside filter.component.ts; 가장 좋은 방법은 무엇입니까?

+0

무엇을하고 싶습니까? 동일한 구성 요소에서 구성 요소의 인스턴스를 가져 오시겠습니까? 우리는 대답 할 수 있도록 당신의 질문을 더 많이 설명 할 수 있습니다. –

답변

0

용액으로부터 취한 구현의 일례이다. 매개 변수가 추상 클래스라는 중요한 사실 중 하나입니다. 인터페이스를 사용할 수 없습니다. 실제로 추상 클래스도 사용할 수 없지만 중첩 된 구성 요소에 공급자를 사용합니다. 내 경우 는 추상 클래스를 확장하고 공급자로이 추상 클래스를 선언해야

export class FilterComponent{ 
    @ContentChildren(FilterItem) filterItems: QueryList<FilterItem>; 
    constructor() {} 

    getItems(){ 
     console.log(this.filterItems); 
     this.filterItems.forEach(i => { 
     console.log('My name is ' + i.name + 'My value is ' + i.getValue()); 
     }); 
    } 
} 

2) 중첩 된 구성 요소입니다. 내 경우

@Component({ 
    selector: 'app-string-filter-item', 
    templateUrl: './string-filter-item.component.html', 
    styleUrls: ['./string-filter-item.component.scss'], 
    providers: [{provide: FilterItem, useExisting: forwardRef(() => StringFilterItemComponent)}] 
}) 
export class StringFilterItemComponent extends FilterItem { 

    selectValue: string; 

    @Input() 
    name:string; 

    caption: 'SHow me smt'; 

    getValue(){ 
    return this.selectValue; 
    } 
} 

문자열 필터 item.component.html 필터 구성 요소를 사용하여

<p> 
    <input type="text" [(ngModel)]="selectValue"> 
</p> 

filter.component.html

<div class="filter-wr"> 
    <ng-content></ng-content> 
</div> 

어디서나 당신이 합니다 (선택 문자열 구성 요소에서 내가 사용하는 또 다른 구성 요소입니다)

<app-filter> 
    <app-select-filter-item name="first"></app-select-filter-item> 
    <app-string-filter-item name="second"></app-string-filter-item> 
    <app-select-filter-item name="third"></app-select-filter-item> 
    <app-string-filter-item name="fourth"></app-string-filter-item> 
</app-filter> 

그게 전부입니다! 관심을 가져 주셔서 감사합니다!

1

양식 컨트롤 인 구성 요소를 만들고 싶습니다. 내가 옳다 경우

대신 ControlValueAccessor를 사용해보십시오 : https://angular.io/api/forms/ControlValueAccessor

이 그들을 사용하는 방법에 대한 예를 많이 있습니다. 여기서 다음

1) 부모 구성 요소가 QueryList 같은 PARAM으로 @ContentChildren 또는 @ViewChildren를 사용하여 하위 구성 요소의 데이터를 얻을 수있다 https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html

export function createCounterRangeValidator(maxValue, minValue) { 
    return (c: FormControl) => { 
    let err = { 
     rangeError: { 
     given: c.value, 
     max: maxValue || 10, 
     min: minValue || 0 
     } 
    }; 

    return (c.value > +maxValue || c.value < +minValue) ? err: null; 
    } 
} 

@Component({ 
    selector: 'counter-input', 
    template: ` 
    <button (click)="increase()">+</button> {{counterValue}} <button (click)="decrease()">-</button> 
    `, 
    providers: [ 
    { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CounterInputComponent), multi: true }, 
    { provide: NG_VALIDATORS, useExisting: forwardRef(() => CounterInputComponent), multi: true } 
    ] 
}) 
export class CounterInputComponent implements ControlValueAccessor, OnChanges { 

    propagateChange:any =() => {}; 
    validateFn:any =() => {}; 

    @Input('counterValue') _counterValue = 0; 
    @Input() counterRangeMax; 
    @Input() counterRangeMin; 

    get counterValue() { 
    return this._counterValue; 
    } 

    set counterValue(val) { 
    this._counterValue = val; 
    this.propagateChange(val); 
    } 

    ngOnChanges(inputs) { 
    if (inputs.counterRangeMax || inputs.counterRangeMin) { 
     this.validateFn = createCounterRangeValidator(this.counterRangeMax, this.counterRangeMin); 
     this.propagateChange(this.counterValue); 
    } 
    } 

    writeValue(value) { 
    if (value) { 
     this.counterValue = value; 
    } 
    } 

    registerOnChange(fn) { 
    this.propagateChange = fn; 
    } 

    registerOnTouched() {} 

    increase() { 
    this.counterValue++; 
    } 

    decrease() { 
    this.counterValue--; 
    } 

    validate(c: FormControl) { 
    return this.validateFn(c); 
    } 
}