首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在HTML模板中声明的组件内部获取组件

在HTML模板中声明的组件内部获取组件
EN

Stack Overflow用户
提问于 2017-10-18 09:02:35
回答 2查看 1.1K关注 0票数 0

我想要创建过滤器组件,它将使用在不同的地方,有不同数量的内部组件。

filter.component.html

代码语言:javascript
复制
<select-filter name="somename" ></select-filter>
<input-filter name="somename"></input-filter>
...

选择过滤器和输入过滤器是实现接口FilterItem的组件。

代码语言:javascript
复制
export interface FilterItem{
  name: string;
  getValue() : any;
}

我希望在getValue()中获取每个组件的实例(例如调用filter.component.ts());最好的方法是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-18 14:29:21

解决方案是下一个

1)父组件使用@ContentChildren或以param作为QueryList的@ViewChildren获取子组件的数据。参数是抽象类这一点很重要。我们不能在那里使用接口。实际上,我们也不能使用抽象类,但是我们在嵌套组件中使用提供程序。在我的例子中

代码语言:javascript
复制
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)嵌套组件应扩展抽象类,并将该抽象类声明为提供程序。在我的情况下

代码语言:javascript
复制
@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

代码语言:javascript
复制
<p>
  <input type="text" [(ngModel)]="selectValue">
</p>

filter.component.html

代码语言:javascript
复制
<div class="filter-wr">
   <ng-content></ng-content>
</div>

在任何地方使用过滤器组件(选择string组件是我使用的另一个组件)

代码语言:javascript
复制
<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>

就这样!谢谢大家的关注!

票数 0
EN

Stack Overflow用户

发布于 2017-10-18 11:32:17

听起来,您想要创建作为表单控件的组件。

如果我是对的,尝试使用ControlValueAccessorhttps://angular.io/api/forms/ControlValueAccessor

关于如何使用它们,有很多例子。下面是一个从https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html获取的实现示例

代码语言:javascript
复制
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);
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46806427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档