我想要创建过滤器组件,它将使用在不同的地方,有不同数量的内部组件。
filter.component.html
<select-filter name="somename" ></select-filter>
<input-filter name="somename"></input-filter>
...选择过滤器和输入过滤器是实现接口FilterItem的组件。
export interface FilterItem{
name: string;
getValue() : any;
}我希望在getValue()中获取每个组件的实例(例如调用filter.component.ts());最好的方法是什么?
发布于 2017-10-18 14:29:21
解决方案是下一个
1)父组件使用@ContentChildren或以param作为QueryList的@ViewChildren获取子组件的数据。参数是抽象类这一点很重要。我们不能在那里使用接口。实际上,我们也不能使用抽象类,但是我们在嵌套组件中使用提供程序。在我的例子中
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;
}
}string-filter-item.component.html
<p>
<input type="text" [(ngModel)]="selectValue">
</p>filter.component.html
<div class="filter-wr">
<ng-content></ng-content>
</div>在任何地方使用过滤器组件(选择string组件是我使用的另一个组件)
<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>就这样!谢谢大家的关注!
发布于 2017-10-18 11:32:17
听起来,您想要创建作为表单控件的组件。
如果我是对的,尝试使用ControlValueAccessor:https://angular.io/api/forms/ControlValueAccessor
关于如何使用它们,有很多例子。下面是一个从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);
}
}https://stackoverflow.com/questions/46806427
复制相似问题