简单地说,我想将Switch组件双向绑定到服务中的布尔值
这样的事情:
@Component({
selector: 'my-switch',
template: '...'
})
export class Switch {
@Input() state: Boolean
toggle() {
if (this.state) {
this.state = false
} else {
this.state = true
}
}
}
@Injectable()
class export FooService {
theBoolean: Boolean
}
@Component({
selector: 'my-app',
template: '<my-switch [(state)]="_foo.theBoolean"></my-switch>{{ _foo.theBoolean }}'
})
export class App {
constructor(private _foo: FooService) {}
}
那么这里应该发生的是,当切换开关时,FooService中的onChanges
事件应该触发,反之亦然。
答案 0 :(得分:3)
要使双向绑定生效,您需要声明一个名为'stateChange'的输出事件
@Output stateChange: EventEmitter<Boolean>=new EventEmitter();
然后在你的切换实现中:
toggle() {
if (this.state) {
this.state = false;
} else {
this.state = true
}
this.stateChange.emit(this.state);
}
在您的HTML模板中:
[(state)]="model"
相当于:
[state]="model" (stateChange)="model=$event"
其中$ event是传递给EventEmitter的emit方法的参数。每当状态发生变化时,它会发出stateChange事件,然后更新父组件中的模型 - 从而使模型保持同步
答案 1 :(得分:0)
您还可以尝试以下
在组件开关中将FooService类型的变量foo定义为@Input(),并将App的foo属性传递给Switch Component su
@Component({
selector: 'my-app',
template: '<my-switch [foo]="_foo"></my-switch>{{ _foo.theBoolean }}'
})
export class App {
constructor(private _foo: FooService) {}
}
export class Switch {
@Input() foo: Foo
toggle() {
this.foo.theBoolean = !this.foo.theBoolean;
}
这样,App和Switch之间只共享一个FooService实例。因此,对它的任何更改(由App或Switch获得)都会反映在另一个组件上。
我希望这会有所帮助
答案 2 :(得分:0)
您还可以注意到,您可以通过利用自定义值访问器轻松实现符合ngModel
/ ngControl
的自定义组件。通过这种方式,您可以使用ngModel
,ngControl
/ ngFormControl
按部分格式(验证,值)制作您的组件,如下所示:
<my-switch [(ngModel)]="_foo.theBoolean"
#ctrl="ngModel" ngControl="switch"></my-switch>
以下是实现此目的的方法:
const SWITCH_VALUE_ACCESSOR = new Provider(NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => Switch), multi: true});
@Component({
selector: 'my-switch',
template: '...'
})
export class Switch implements ControlValueAccessor {
state: boolean;
onChange = (_) => {};
onTouched = () => {};
writeValue(value: any): void {
this.state = value;
}
toggle() {
if (this.state) {
this.state = false
} else {
this.state = true;
}
this.onChange(this.state);
}
registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
registerOnTouched(fn: () => void): void { this.onTouched = fn; }
}
有关详细信息,请参阅此链接: