当我们实现CheckboxControlValueAccessor时,我们得到以下错误:
类型具有私有属性'_renderer'
的单独声明代码:
export class NHCheckbox implements CheckboxControlValueAccessor {
_align = "right";
_label = ""; // Label
_required = false;
_tooltip: string = null;
constructor(
private _renderer: Renderer,
private _elementRef: ElementRef
) {
}
CheckboxControlValueAccessor类:
export declare class CheckboxControlValueAccessor implements ControlValueAccessor {
private _renderer;
private _elementRef;
onChange: (_: any) => void;
onTouched: () => void;
constructor(_renderer: Renderer, _elementRef: ElementRef);
writeValue(value: any): void;
registerOnChange(fn: (_: any) => {}): void;
registerOnTouched(fn: () => {}): void;
setDisabledState(isDisabled: boolean): void;
}
我们做错了什么?
Angular Version:4.1.3 打字稿:2.3.4
答案 0 :(得分:4)
当我在Angular 2+中需要一个复选框组件时,做同样的事情似乎很直观。当你可以从一个复选框开始时,为什么要从一般控制开始,对吧?在花了太多时间之后,我决定放弃并改用ControlValueAccessor
。
正如您在this plnkr中所看到的,复选框组件可以这样写:
import { Component, /*Input,*/ Renderer, ElementRef, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'my-checkbox',
template: `
<div class="checkbox-container">
<input type="checkbox" id="{{ controlID }}"
[checked]="checked" (change)="onChange($event)" />
<label for="{{ controlID }}"></label>
</div>
`,
styles: [`
.checkbox-container {
background-color: #ddd;
width: 20px;
height: 20px;
position: relative;
}
`, `
.checkbox-container input[type="checkbox"] {
visibility: hidden;
}
`, `
.checkbox-container label {
width: 18px;
height: 18px;
position: absolute;
top: 1px;
left: 1px;
background-color: white;
}
`,`
.checkbox-container label:before {
content: '';
width: 16px;
height: 8px;
border: 4px solid #000;
position: absolute;
border-top: none;
border-right: none;
transform: rotate(-50deg);
top: 1px;
left: 1px;
opacity: 0;
}
`, `
.checkbox-container input[type="checkbox"]:checked + label:before {
opacity: 1;
}
`],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CheckboxComponent),
multi: true
}
]
})
export class CheckboxComponent implements ControlValueAccessor {
static idCounter: Number = 0;
controlID: String;
//@Input() checked: Boolean;
checked: Boolean;
constructor(private renderer: Renderer, private elementRef: ElementRef) {
this.controlID = "myCheckbox" + CheckboxComponent.idCounter++;
}
propagateChange = (_: any) => { };
onTouchedCallback: () => {};
writeValue(value: any) {
if ((value !== undefined) && (value !== null)) {
this.checked = value;
}
}
registerOnChange(fn: any) {
this.propagateChange = fn;
}
registerOnTouched(fn: any) {
this.onTouchedCallback = fn;
};
onChange(event) {
this.checked = event.target.checked;
this.propagateChange(event.target.checked);
}
}
可以像这样使用:
<form #form="ngForm" (ngSubmit)="submit(form.value)">
<div>
<h2>Checkbox Demo Using {{ framework }}</h2>
</div>
<div>
<my-checkbox name="b1" [(ngModel)]="b1"></my-checkbox>
<my-checkbox name="b2" [(ngModel)]="b2"></my-checkbox>
<my-checkbox name="b3" [(ngModel)]="b3"></my-checkbox>
</div>
</form>
<pre>{{ form.value | json }}</pre>
注意:
controlID
必须是唯一的,可以使用静态计数器显示。 checked
成为一个
输入()变量,因为您可以使用外部ngModel
变量完成相同的操作。