Angular2:在放弃文本输入更改后更新视图

时间:2018-10-31 10:58:56

标签: angular angular-components

我有一系列文本区域,可以分别进行更新,更改可以保存或放弃。每个文本区域均由一个对象表示,以跟踪更改并启用/禁用某些按钮。一切工作正常,但是在丢弃之后,对象没有更改,但是视图未更新。当我更改对象内部的某些内容时,它只会更新,因此我尝试制作该对象的“真实”副本并将这些值分配给实际对象,但这也不起作用。 到目前为止,我的代码:

HTML:

   <ng-container *ngFor="let itemId of itemIds">
  <div>
        <div>
            <textarea #message (keydown)="enableButton(itemId)" rows="5" cols="50"[(value)]="getMessageDetails(itemId).message"></textarea>
        </div>
    </div>
    <div>
        <button [disabled]="!getMessageDetails(itemId).changedText" (click)="saveMessageChanges(itemId, message.value)">Save Changes</button>
        <button [disabled]="!getMessageDetails(itemId).changedText" (click)="discardChanges(itemId)">Discard Changes</button>
    </div>
</ng-container>

组件:

    itemIds = [2,4];

  myMessages = [
    {
      id: 2,
      message: 'hello',
      changedText: false
    },
    {
      id: 4,
      message: 'world',
      changedText: false
    }
  ]

enableButton(itemId){
    this.myMessages.map( y => {if (y.id === itemId) {
      y.changedText = true;
    }});
  }

getMessageDetails(itemId){
    let myMessage = this.myMessages.find(y => y.id === itemId);
    return myMessage;
  }

saveMessageChanges(itemId, message){
    this.myMessages.map( y => {if (y.id === itemId) {
      y.message = message;
      y.changedText = false;
    }});
  }
discardChanges(itemId){
    let tempMessage = Object.assign({},(this.myMessages.find(y => y.id === itemId)));

    let myMessage = this.myMessages.find(y => y.id === itemId);

    myMessage.changedText = false;
    myMessage.message =  tempMessage.message; // <- no object change detected
    //myMessage.message = " " + tempMessage.message; // <- this works
    return myMessage;
  }

每当我在邮件中添加空格时,它将起作用。

我在这里创建了一个堆叠闪电战: https://stackblitz.com/edit/angular-m5dbj4

1 个答案:

答案 0 :(得分:1)

未检测到更改,因为列表IsCancellationRequested中实际上没有更改。如果将Task添加到HTML并将文本插入文本区域,则会看到列表的内容没有改变。在myMessages中,您只需将“ hello”再次分配给已经包含字符串“ hello”的变量。因此没有变化。 如果您在{{myMessages | json }}中的消息中添加空格(如您所述),则实际上将值从“ hello”更改为“ hello”->值已更改。

但是,您可以通过持有“上一个”列表来跟踪此列表的原始条目和ngModel的用法,从而解决此问题。

将文本区域更改为

discardChanges

您的组件:

discardChanges

我避免了组件中的某些方法,因为它们与本示例无关。只需为<textarea #message (keydown)="enableButton(itemId)" rows="5" cols="50" [(ngModel)]="getMessageDetails(itemId).message"></textarea> 处的变量@Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: [ './app.component.css' ] }) export class AppComponent implements OnInit { itemIds = [2,4]; myMessages = [ { id: 2, message: 'hello', changedText: false }, { id: 4, message: 'world', changedText: false } ] previous = [] ngOnInit() { this.previous = this.getDeepCopy(this.myMessages); } saveMessageChanges(itemId, message){ this.myMessages.map( y => {if (y.id === itemId) { y.message = message; y.changedText = false; }}); this.previous = this.getDeepCopy(this.myMessages); } discardChanges(itemId){ this.myMessages = this.getDeepCopy(this.previous); let myMessage = this.myMessages.find(y => y.id === itemId); return myMessage; } getDeepCopy( list ) { return list.map(x => Object.assign({}, x)); } } 分配一个深层副本,如果按保存,也可以这样做。如果要放弃更改,请再次将列表previous的深层副本分配给ngOnInit

有了这个,您的视图就会更新,因为现在变量值发生了变化。