包角组件

时间:2019-03-20 01:20:18

标签: javascript angular angular-material material-design

我写道,我需要自己包装一个mat-slide-toggle组件:

mytoggle.component.ts

import { Component, OnInit, Input, forwardRef, ViewChild, ElementRef } from '@angular/core';
import {MatSlideToggle, MatSlideToggleChange} from '@angular/material/slide-toggle';
import { NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'ng7-common-ng7-slide',
  templateUrl: 'ng7-slide.component.html',
  styles: [],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => Ng7SlideComponent),
      multi: true
    }
  ]
})
export class Ng7SlideComponent extends MatSlideToggle {

}

mytoggle.component.html

<mat-slide-toggle
    [checked]="checked"
    [disabled]="disabled">
    {{label}}
</mat-slide-toggle>

在我的应用中,我正在这样使用

app.component.html

<form class="example-form" [formGroup]="formGroup" (ngSubmit)="onFormSubmit(formGroup.value)" ngNativeValidate>


  <!-- THIS WORKS <mat-slide-toggle formControlName="slideToggle">Enable Wifi</mat-slide-toggle> -->
  <ng7-common-ng7-slide formControlName="slideToggle" label="test me!">
</ng7-common-ng7-slide>

  <button mat-rasied-button type="submit">Save Settings</button>
</form>

app.component.ts

import { Component } from '@angular/core';
import { FormGroup, FormControl, FormBuilder } from '@angular/forms';
import { MatSlideToggleChange } from '@angular/material/slide-toggle';

@Component({
  selector: 'home-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {

  formGroup: FormGroup;

  constructor(formBuilder: FormBuilder) {
    this.formGroup = formBuilder.group({
      slideToggle: false
    });
  }

  onFormSubmit(formValue: any) {
    alert(JSON.stringify(formValue, null, 2));
  }

}

因此onFormSubmit方法上的formValue始终会警告“ slideToggle”:false(无论是否选中),当我使用mat-slide-toggle时,它会根据切换状态正确地警告true或false。

还有其他事情要做吗?我只需要扩展组件和所有事件。

1 个答案:

答案 0 :(得分:0)

经过研究,我得到了一些效果很好的东西。

我导入了一个实现基本值acessors方法的抽象类:

https://stackoverflow.com/a/45480791/2161180

import { ControlValueAccessor } from '@angular/forms';

export abstract class AbstractValueAccessor implements ControlValueAccessor {
    innerValue: any = '';
    get value(): any { return this.innerValue; }
    set value(v: any) {
      if (v !== this.innerValue) {
        this.innerValue = v;
        this.onChange(v);
      }
    }

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

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

然后我创建了扩展它的组件:

import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { Component, Input, forwardRef } from '@angular/core';
import { AbstractValueAccessor } from '../abstract.component';

    @Component({
      selector: 'my-switch',
      templateUrl: './my-switch.component.html',
      styleUrls: ['./my-switch.component.css'],
      providers: [
        {
          provide: NG_VALUE_ACCESSOR,
          multi: true,
          useExisting: forwardRef(() => MySwitchComponent)
        }
      ]
    })
    export class MySwitchComponent extends AbstractValueAccessor {

      @Input() label: string;
      @Input() checked: boolean;
      @Input() disabled: boolean;

    }

html:

<mat-slide-toggle
    [(ngModel)]="value"
    [checked]="checked"
    [disabled]="disabled">
  {{label}}
</mat-slide-toggle>

模块:

import { FormsModule } from '@angular/forms';
import { MatSlideToggleModule } from '@angular/material';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MySwitchComponent } from './my-switch.component';

@NgModule({
  declarations: [MySwitchComponent],
  imports: [
    CommonModule,
    MatSlideToggleModule,
    FormsModule
  ],
  exports: [
    MySwitchComponent
  ]
})
export class MySwitchModule { }

并使用它:

<form [formGroup]="fb">
  <my-switch formControlName="inputSwitch" label="Toggle-me!"></my-switch> 
  <strong> Value: </strong> {{inputSwitch}}
</form>

<my-switch [(ngModel)]="inputSwitchNgModel" label="Toggle-me!"></my-switch>
<strong> Value: </strong> {{inputSwitchNgModel}}