扩展Angular 2 ngModel指令以使用observable

时间:2016-08-09 07:41:37

标签: angular rxjs observable

Angular 2 ngModel指令适用于

等变量和函数

<input [ngModel]="myVar" (ngModelChange)="myFunc($event)" />

而不是变量和函数,我想使用BehaviorSubjects而不是

<input [ngModel]="mySubject | async" (ngModelChange)="mySubject.next($event)" />

是否有一种安全的方法来扩展ngModel或使用某种宏来减少模板中的重复?

<input [myNewNgModel]="mySubject" />

3 个答案:

答案 0 :(得分:0)

我不知道您为什么不只使用反应形式,但这是一个有趣的难题。我创建了一条指令,该指令会将模型值更改为BehaviorSubject的值。任何更改都会在.next上为您调用BehaviorSubject

用法看起来像这样

<input type="text" [ngModel]="ngModelValue" appRxModel> 

这是stackblitz,请享受

答案 1 :(得分:0)

我想出了一种类似于@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>
  

有一些变化,以防需要输入参考值   并且您不想进行第二次订阅(使用模板变量)。

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>

答案 2 :(得分:0)

您真的要为表单中的每个输入字段创建一个可观察对象吗?我使用的模式是对整个表单的模型有一个可观察的模式,将其克隆为一个视图变量,然后将其绑定到该变量,然后让表单的提交处理程序将新模型推回服务。

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