仅以一种方式绑定

时间:2018-08-23 14:00:33

标签: angular data-binding angular6 subscribe behaviorsubject

我有一个带有用户的表格,单击时要更新。我创建了一个服务来做到这一点。

问题在于,当我开始编辑表格编辑内容时,在编辑表单中,就像是双向绑定一样,我不想同时编辑两面。如果在单击编辑按钮时取出[(ngModel)]上的(),则不会填充已编辑的数据。

点击单元格

this.dataService.setUser(row);

我的dataService

public currentUser = new Subject<User>();
setUser(user) {
    this.currentUser.next(user);
}

我的编辑组件

this.dataService.currentUser.subscribe(value => this.user = value);

我到处搜索并且找不到答案,也许是在中间创建一个对象然后将其销毁,但不知道该怎么做。

这是图像,imgur.com/a/yq3yFNC事情是我不想双向绑定,因为首先我必须按下面的按钮进行验证。我只需要以一种方式绑定。 (目前,如果我在下面进行编辑,它将在编辑我的表格)

Here is the example code

我不能使用[value][ngModel],因为它没有将值返回给我的对象用户。这就是为什么我使用[(ngModel)]

2 个答案:

答案 0 :(得分:0)

发生这种情况是因为您的“读取”显示和“编辑”显示绑定到同一对象。您仍然想使用双向绑定,但是要将它们绑定到不同的对象。

不要将编辑对象分配给“读取”显示所使用的同一对象,而是应复制对象的属性。

编辑组件

this.dataService.currentUser.subscribe(value => this.user = {...value});

然后,每当要保存值时,都可以将属性分配回原始对象,也可以简单地将旧对象替换为新对象。

您可以通过存储对原始对象的引用以及编辑组件将要操作的复制值来实现此目的的一种方法:

this.dataService.currentUser.subscribe(value => {
  this.original = value;
  this.user = {...value};
});

save() {
  Object.assign(this.user, this.original)
}

注意:这是一个浅表副本,意味着将复制数字和字符串之类的简单值,但对象引用将保持不变。如果您需要深层副本,可以在SO上进行搜索-针对该问题有很多不同的解决方案。


解决错误问题的旧答案

简短的答案是您的编辑单元格不知道其数据已更改。因为您单击的是其他组件,所以Angular仅重新检查与之交互的组件。您需要手动告诉Angular组件已更改

编辑组件

constructor(private changeDetector: ChangeDetectorRef) {}

this.dataService.currentUser.subscribe(value => {
  this.user = value;
  this.changeDetector.markForCheck();
});

更详细的解释:https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html

答案 1 :(得分:0)

您可以使用[ngModel]和(ngModelChange)代替[[ngModel)]

Agustin123输入到第二次编辑后,您可以获得所需的输出

the online example

 <!-- <input [(ngModel)]="user.name"> -->

 <input [ngModel]="user.name" (ngModelChange)="onChange($event)" >
  

ngModel数据属性设置元素的value属性,ngModelChange事件属性侦听元素值的更改。

引用


旧答案

您可以在 data.service

中在complete之后使用next

在线示例: https://stackblitz.com/edit/httpsstackoverflowcomquestions51987641angular-6-bind-just-in-on?file=src/app/data.service.ts

  setUser(user) {
    this.currentUser.next(user);
    this.currentUser.complete();
  }