简体   繁体   English

Angular 2 - 自定义表单控件 - 禁用

[英]Angular 2 - Custom Form Control - Disable

I have created a custom control using ControlValueAccessor that is composed of an input[type=text] and a datepicker. 我使用ControlValueAccessor创建了一个自定义控件,它由input[type=text]和一个datepicker组成。

When I use it in template-driven forms everything works fine. 当我在模板驱动的表单中使用它时一切正常。 But when I use the model-driven approach (reactive forms), the disable() method on the form control doesn't seem to have any effect whatsoever. 但是当我使用模型驱动的方法(反应形式)时,表单控件上的disable()方法似乎没有任何效果。

Is it possible to disable/enable my custom control programmatically as I do with every other form control in model-driven forms 是否可以以编程方式禁用/启用我的自定义控件,就像我在模型驱动的表单中使用其他每个表单控件一样

EDIT 编辑

I should note that I'm using Angular v2.1.0 and that my methodology is pretty much the same as this as I have been using it as a guide. 我要指出,我采用了棱角分明的v2.1.0,我的方法是几乎一样的这个 ,因为我一直在使用它作为指南。

EDIT 编辑

This is my custom control: 这是我的自定义控件:

@Component({
  selector: 'extended-datepicker',
  templateUrl: './extended-datepicker.component.html',
  styleUrls: ['./extended-datepicker.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => ExtendedDatepickerComponent),
      multi: true
    }
  ]
})
export class ExtendedDatepickerComponent implements OnInit, ControlValueAccessor {
  isDatepickerActive: boolean = false;
  _selectedDate: Date;
  selectedDateString: string = "";
  @Input() disabled: boolean;
  @Input() mask: any;
  @Input() required: boolean;

  @ViewChild('textInput') textInput: ElementRef;

  get selectedDate(): Date {
    return this._selectedDate;
  }

  set selectedDate(value: Date) {
    this.selectedDateString = moment(value).format(STANDARD_DATE_FORMAT);
    this._selectedDate = value;
  }

  propagateChange: Function;

  @ViewChild(DatePickerComponent) datepicker: DatePickerComponent;

  constructor() {
  }

  writeValue(value: Date) {
    if (value) {
      this.selectedDate = value;
      this.selectedDateString = moment(value).format(STANDARD_DATE_FORMAT);
    }
  }

  registerOnTouched(): void {
  }

  registerOnChange(fn: Function) {
    this.propagateChange = fn;
  }
  // ...

This is the control's template: 这是控件的模板:

<div class="calendar-wrapper row-small-margin" 
     (clickOutside)="isDatepickerActive = false;">

  <div class="col-xs-10 col-small-padding">
    <div class="input-group">

      <span class="input-group-addon" role="button" (click)="prevDay()" 
            *ngIf="selectedDate">
        <i class="fa fa-chevron-left"></i>
      </span>

      <input #textInput [textMask]="{mask: mask}" 
             [(ngModel)]="selectedDateString" 
             (ngModelChange)="inputChange()"
             class="form-control" [required]="required" 
             [disabled]="disabled" (keyup)="onKeyPressed($event)">

      <span class="input-group-addon" role="button" (click)="nextDay()" 
            *ngIf="selectedDate">
        <i class="fa fa-chevron-right"></i>
      </span>
    </div>

    <div *ngIf="isDatepickerActive" class="datepicker-wrapper">
      <datepicker [(ngModel)]="selectedDate" (ngModelChange)="dateChange()" 
                  [showWeeks]="false" [required]="required"
                  [formatDay]="dd" [formatMonth]="MM" [formatYear]="yyyy" 
                  [disabled]="disabled">
      </datepicker>
    </div>
  </div>

  <div class="col-xs-2 col-small-padding">
    <button class="btn btn-sm btn-datepicker" [disabled]="disabled"
        (click)="toggleDatePicker()" type="button">
      <img src="/assets/img/image.png">
    </button>
  </div>

</div>

And this is what I do in my form component: 这就是我在表单组件中所做的事情:

this.myForm.controls['pickDate'].valueChanges.subscribe(val => {
  if (!val) {
    this.myForm.controls['date'].disable(); // This line here does nothing
  }
});

How is it possible to respond to that disable() call inside my extended-datepicker and act accordingly? 如何响应我的extended-datepicker中的disable()调用并相应地采取行动?

Your component needs to implement the setDisabledState function which is defined in the ControlValueAccessor interface (see docs ). 您的组件需要实现在ControlValueAccessor接口中定义的setDisabledState函数(请参阅docs )。

Eg (assuming the renderer has been injected in the constructor): 例如(假设渲染器已在构造函数中注入):

setDisabledState(isDisabled: boolean) {
    this.renderer.setElementProperty(this.textInput.nativeElement, 'disabled', isDisabled);
    // disable other components here
}

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

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