如何在 Angular 2/4 中创建通用控件?

2024-03-04

我必须创建一个控件/模板/通用 html,其中有一个下拉菜单。该公共控件将调用我的数据服务并将该下拉列表与数据绑定。

我可以创建一个组件并将其 HTML 作为下拉菜单,然后在所有父组件中调用该组件的选择器。但是,我想要的是我需要将密钥传递给这个公共控件,并且该密钥将被发送到服务,并且服务将仅提供匹配的记录,并且根据这些记录下拉列表将被绑定。

这是我的伪代码:

<div class="form-group">
            <label class="col-md-2 control-label">Forms</label>
            <div class="col-md-3">
              <select class="form-control">
                <option value="Expression">Expression</option>
                <option value="Tender">Tender</option>
                <option value="Other">Other</option>
              </select>
            </div>
          </div>

而不是这个我想要这样的东西:

 <div class="form-group">
            <label class="col-md-2 control-label">Forms</label>
            <div class="col-md-3">
             COMMONCONTROL('KEY')
            </div>
          </div>

在 Angular 2 中实现这一目标的方法是什么?

Thanks


您应该只创建一个实现以下功能的组件ControlValueAccessor https://angular.io/api/forms/ControlValueAccessor接口,然后将其与ngModel选择元素的。为了更好地使用,我建议首先实现一个抽象类:

import { Provider, forwardRef, Type, OpaqueToken } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

export abstract class AbstractValueAccessor implements ControlValueAccessor {
    private _value: any = null;
    public onChange = (_) => { };
    public onTouched = () => { };

    public get value(): any {
      return this._value;
    }

    public set value(v: any) {
      if (v !== this._value) {
        this._value = v;
        this.onChange(v);
      }
    }

    public writeValue(value: any) {
      this._value = value;
      this.onChange(value);
    }

    public registerOnChange(fn: (_: any) => void): void {
      this.onChange = fn;
    }

    public registerOnTouched(fn: () => void): void {
      this.onTouched = fn;
    }
}

export function MakeProvider(type: any) {
  return {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => type),
    multi: true
  };
}

有关实现的值访问器的外观和工作原理的更多信息可以找到here https://angular.io/api/forms/DefaultValueAccessor。有关角度外观中各种评估器实现的信息here https://angular.io/api?query=ValueAccessor.

然后用它扩展你的组件:

import { Component, ChangeDetectionStrategy, Input, SimpleChanges, OnChanges } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { AbstractValueAccessor, MakeProvider } from './abstract-value-accessor';

@Component({
    selector: 'custom-select',
    templateUrl: './custom-select.component.html',
    providers: [MakeProvider(CustomSelectComponent)],
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class CustomSelectComponent extends AbstractValueAccessor implements OnChanges {
    private data$$ = new BehaviorSubject<any[]>([]);

    @Input()
    public dataKey: string;

    public data$ = this.data$$.asObservable();

    public get hasData$() {
        return this.data$.map(data => data.length > 0);
    }

    constructor(private dataService: MyDataService) {
        super();
    }

    ngOnChanges(changes: SimpleChanges) {
        if(changes.dataKey && changes.dataKey.currentValue) {
           this.getData(changes.dataKey.currentValue);
        }
    }

    private getData(dataKey: string) {
        this.dataService.get(dataKey).take(1).subscribe(data => this.data$$.next(data));
    }
}

在组件的模板中,将其绑定到选择:

<select [(ngModel)]="value" *ngIf="hasData$ | async">
    <option [value]="option.value" *ngFor="let option of data$ | async">{{ option.name }}</option>
</select>

然后你可以在任何你想要的地方使用它,例如:

<custom-select dataKey="test"></custom-select>

注意:此代码未经测试,仅提供正确方向的方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Angular 2/4 中创建通用控件? 的相关文章

随机推荐