简体   繁体   English

以角度包裹组件

[英]Wraping components in angular

I need to wrap a mat-slide-toggle component on my own, I wrote: 我需要自己包装一个mat-slide-toggle组件,我写道:

mytoggle.component.ts 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 {

}

And mytoggle.component.html : mytoggle.component.html

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

and in my app I'm using like this: 在我的应用程序中,我使用这样的:

app.component.html 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 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));
  }

}

So the formValue on onFormSubmit method always alerts "slideToggle":false no matter is it is checked or not, when I use mat-slide-toggle it alerts true or false according with the toggle state correctly. 因此onFormSubmit方法上的formValue总是警告“slideToggle”:false无论是否检查,当我使用mat-slide-toggle时,它会根据切换状态正确地提醒true或false。

Are there anything else to do? 还有什么可做的吗? I just need to extend the component and all event. 我只需要扩展组件和所有事件。

After some research I got something that works well.. 经过一些研究,我得到了一些运作良好的东西

I imported an abstract class that implements the basic value acessors methods: 我导入了一个实现基本值acessors方法的抽象类:

https://stackoverflow.com/a/45480791/2161180 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; }
}

Then I created my component extending it: 然后我创建了扩展它的组件:

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: HTML:

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

module: 模块:

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 { }

And to use it: 并使用它:

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

or 要么

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM