【问题标题】:Angular2: update view after discarding change in text inputAngular2:丢弃文本输入中的更改后更新视图
【发布时间】:2018-10-31 10:58:56
【问题描述】:

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

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

【问题讨论】:

    标签: angular angular-components


    【解决方案1】:

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

    但是,您可以通过保存“先前”列表来跟踪列表的原始条目和 ngModel 的使用来克服这个问题。

    将文本区域改为

    <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));
      }
    }
    

    我避免了组件中的一些方法,因为它们与本示例无关。只需在ngOnInit 处为变量previous 分配一个深层副本,如果您按保存,也可以执行此操作。如果要放弃更改,请将列表previous 的深层副本再次分配给myMessages

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

    【讨论】:

    • 非常感谢,它成功了!我也在考虑复制,但我想,也许有办法绕过它,我没有考虑过。
    猜你喜欢
    • 2017-10-07
    • 2016-04-08
    • 2016-04-02
    • 2023-03-17
    • 2015-10-20
    • 2016-12-18
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    相关资源
    最近更新 更多