扩展 Angular 2 ngModel 指令以使用可观察对象
Extending Angular 2 ngModel directive to use observables
Angular 2 ngModel
指令适用于像
这样的变量和函数
<input [ngModel]="myVar" (ngModelChange)="myFunc($event)" />
我想使用 BehaviorSubjects 而不是变量和函数
<input [ngModel]="mySubject | async" (ngModelChange)="mySubject.next($event)" />
有没有安全的方法来扩展 ngModel 或使用某种宏来减少模板中的重复?
<input [myNewNgModel]="mySubject" />
我不知道您为什么不直接使用响应式表单,但这是一个有趣的谜题。我创建了一个指令,将模型值更改为 BehaviorSubject
的值。任何更改都会在 BehaviorSubject
上为您调用 .next
。
用法如下所示
<input type="text" [ngModel]="ngModelValue" appRxModel>
这里是stackblitz,欣赏
我想出了与@Adbel 类似的方法。不确定这其中的内在含义,但能得到一些反馈会很棒。 Stackbliz code
Your.component.ts
export class AppComponent {
email = new BehaviorSubject("UnwrappedMe ");
emailHandler(input) {
this.email.next(input);
}
}
Your.component.html
<form class="mx-3">
<input [ngModel]="email | async"
(ngModelChange)="emailHandler($event)"
name="email" type="email"
id="email" placeholder="Enter email">
</form>
<p class="mx-3"> {{ email | async }} </p>
A little variation in case you need to get a ref to your input value
and you do not want to make a second subscription (use template vars).
Your.component.html
<form class="mx-3">
<input [ngModel]="email | async" #emailref
(ngModelChange)="emailHandler($event)"
name="email" type="email"
id="email" placeholder="Enter email">
</form>
<p class="mx-3"> {{ emailref.value }} </p>
您真的要为表单中的每个输入字段创建一个可观察对象吗?我使用的模式是为整个表单的模型设置一个可观察对象,将其克隆为一个视图变量,然后您可以绑定到该视图变量,然后让表单的提交处理程序将新模型推送回服务。
user$ = this.userService.user$;
save(user: User) {
this.userService.save(user);
}
并在视图中
<form *ngIf="user$ | async | clone as user" #userForm="ngForm" (submit)="userForm.form.valid && save(user)">
<label>
Firstname
<input name="firstname" [(ngModel)]="user.firstname" required>
</label>
<label>
Lastname
<input name="lastname" [(ngModel)]="user.lastname" required>
</label>
<button>Save</button>
</form>
克隆管道看起来像这样
export const clone = (obj: any) =>
Array.isArray(obj)
? obj.map(item => clone(item))
: obj instanceof Date
? new Date(obj.getTime())
: obj && typeof obj === 'object'
? Object.getOwnPropertyNames(obj).reduce((o, prop) => {
o[prop] = clone(obj[prop]);
return o;
}, {})
: obj;
import { Pipe, PipeTransform } from '@angular/core';
import { clone } from './clone';
@Pipe({
name: 'clone'
})
export class ClonePipe implements PipeTransform {
transform(value: any): any {
return clone(value);
}
}
我在这里用我的状态管理库写了一篇关于这个模式的文章。 https://medium.com/@adrianbrand/angular-state-management-with-rxcache-468a865fc3fb
Angular 2 ngModel
指令适用于像
<input [ngModel]="myVar" (ngModelChange)="myFunc($event)" />
我想使用 BehaviorSubjects 而不是变量和函数
<input [ngModel]="mySubject | async" (ngModelChange)="mySubject.next($event)" />
有没有安全的方法来扩展 ngModel 或使用某种宏来减少模板中的重复?
<input [myNewNgModel]="mySubject" />
我不知道您为什么不直接使用响应式表单,但这是一个有趣的谜题。我创建了一个指令,将模型值更改为 BehaviorSubject
的值。任何更改都会在 BehaviorSubject
上为您调用 .next
。
用法如下所示
<input type="text" [ngModel]="ngModelValue" appRxModel>
这里是stackblitz,欣赏
我想出了与@Adbel 类似的方法。不确定这其中的内在含义,但能得到一些反馈会很棒。 Stackbliz code
Your.component.ts
export class AppComponent {
email = new BehaviorSubject("UnwrappedMe ");
emailHandler(input) {
this.email.next(input);
}
}
Your.component.html
<form class="mx-3">
<input [ngModel]="email | async"
(ngModelChange)="emailHandler($event)"
name="email" type="email"
id="email" placeholder="Enter email">
</form>
<p class="mx-3"> {{ email | async }} </p>
A little variation in case you need to get a ref to your input value and you do not want to make a second subscription (use template vars).
Your.component.html
<form class="mx-3">
<input [ngModel]="email | async" #emailref
(ngModelChange)="emailHandler($event)"
name="email" type="email"
id="email" placeholder="Enter email">
</form>
<p class="mx-3"> {{ emailref.value }} </p>
您真的要为表单中的每个输入字段创建一个可观察对象吗?我使用的模式是为整个表单的模型设置一个可观察对象,将其克隆为一个视图变量,然后您可以绑定到该视图变量,然后让表单的提交处理程序将新模型推送回服务。
user$ = this.userService.user$;
save(user: User) {
this.userService.save(user);
}
并在视图中
<form *ngIf="user$ | async | clone as user" #userForm="ngForm" (submit)="userForm.form.valid && save(user)">
<label>
Firstname
<input name="firstname" [(ngModel)]="user.firstname" required>
</label>
<label>
Lastname
<input name="lastname" [(ngModel)]="user.lastname" required>
</label>
<button>Save</button>
</form>
克隆管道看起来像这样
export const clone = (obj: any) =>
Array.isArray(obj)
? obj.map(item => clone(item))
: obj instanceof Date
? new Date(obj.getTime())
: obj && typeof obj === 'object'
? Object.getOwnPropertyNames(obj).reduce((o, prop) => {
o[prop] = clone(obj[prop]);
return o;
}, {})
: obj;
import { Pipe, PipeTransform } from '@angular/core';
import { clone } from './clone';
@Pipe({
name: 'clone'
})
export class ClonePipe implements PipeTransform {
transform(value: any): any {
return clone(value);
}
}
我在这里用我的状态管理库写了一篇关于这个模式的文章。 https://medium.com/@adrianbrand/angular-state-management-with-rxcache-468a865fc3fb