我已经开始寻找到这样的事情表单控件集成与我的图书馆ng-app-state。如果你喜欢制作非常通用的类型库,然后阅读。但要小心,这很长!最后,你应该能够在你的模板使用此:
<input [subjectModel]="subject">
我已经做了验证的概念,这个答案的前半部分,后半部分我认为是正确的,但被警告没有写在这个答案中的实际代码被测试。我很抱歉,但这是我现在要提供的最好的。 :)
您可以编写自己的指令,称为subjectModel
将主题连接到表单组件。以下是关键部分,减去清理之类的东西。它依赖于ControlValueAccessor
接口,因此Angular包含必要的适配器,以将其与所有标准HTML表单元素和挂钩,只要它们使用ControlValueAccessor
(它会与您在野外找到的任何自定义表单控件一起使用)是推荐的做法)。
@Directive({ selector: '[subjectModel]' })
export class SubjectModelDirective {
private valueAccesor: ControlValueAccessor;
constructor(
@Self() @Inject(NG_VALUE_ACCESSOR)
valueAccessors: ControlValueAccessor[],
) {
this.valueAccessor = valueAccessors[0]; // <- this can be fancier
}
@Input() set subjectModel(subject: Subject) {
// <-- cleanup here if this was already set before
subject.subscribe((newValue) => {
// <-- skip if this is already the value
this.valueAccessor.writeValue(newValue);
});
this.valueAccessor.registerOnChange((newValue) => {
subject.next(newValue);
});
}
}
我们可以停在这里,你就可以在你的模板来写:
<input [subjectModel]="subject" [ngDefaultControl]>
这额外[ngDefaultControl]
存在手动引起的角度,以提供所需ControlValueAccessor
我们的指令。其他类型的输入(如单选按钮和选择)需要一个不同的额外指令。这是因为Angular不会自动将值访问器附加到每个表单组件,只有那些也有ngModel
,formControl
或formControlName
的值。
如果您想额外花费一些时间来消除对这些额外指令的需求,您必须将其基本上复制到您的代码中,但修改它们的选择器以激活您的新subjectModel
。这是没有经过测试的一部分,但我相信你可以这样做:
// This is copy-paste-tweaked from
// https://angular.io/api/forms/DefaultValueAccessor
@Directive({
selector: 'input:not([type=checkbox])[subjectModel],textarea[subjectModel]',
host: {
'(input)': '_handleInput($event.target.value)',
'(blur)': 'onTouched()',
'(compositionstart)': '_compositionStart()',
'(compositionend)': '_compositionEnd($event.target.value)'
},
providers: [DEFAULT_VALUE_ACCESSOR]
})
export class DefaultSubjectModelValueAccessor extends DefaultValueAccessor {}
信贷对我的这种理解去ngrx-forms,其全球员工总数这种技术。
当输入值发生变化时,您会发生什么? “主题”是单向的。 '[ngModel] =“subject | async”(ngModelChange)=“subject。下一个($ event)“'可能工作 –
@GünterZöchbauer['Subject'](http://reactivex.io/rxjs/class/es6/Subject.js~Subject.html)是双向的,它既是一个['Observer'](http://reactivex.io/rxjs/class/es6/MiscJSDoc.js~ObserverDoc.html)和['Observable'](http://reactivex.io/rxjs/class/es6/ Observable.js〜Observable.html)。如果它总是[[BehaviorSubject]](http://reactivex.io/rxjs/class/es6/BehaviorSubject.js~BehaviorSubject.html),我也很好。帮助(因为有一个方法来访问当前值) – mhelvens
你有没有想过这个? – DarkNeuron