如何在允许按钮后修复损坏的ngModel?

时间:2017-04-28 19:35:58

标签: angular

我有以下代码:

模板:

<button *ngFor="name of students"
        (click)="modifyText($event.currentTarget)">{{name}}</button>

打字稿

this.students = ["Carl", "Rob", "Joy];
public modifyText(htmlElement: HTMLElement) {
    this.dataset.edit = !this.dataset.edit;
    htmlElement.contentEditable = this.dataset.edit;
    htmlElement.focus();
}

问题是,只要我使用内容可编辑修改内容,我似乎就失去了对{{name}}的绑定,就像我在页面上有一个单独的按钮一样:

<button (click)="students[0] = 'Amy'">Manual Set Name</button>

学生阵列发生了变化,但是当我看到按钮的文字时,它就是我在“满足”中“编辑”的内容,并且根本没有显示Amy。

2 个答案:

答案 0 :(得分:2)

我建议您在嵌入式组件中使用ngModelpure Angular two ways data binding

import {Component, Input, Output, EventEmitter} from '@angular/core';

@Component({
  selector: 'editable-button',
  template: `
    <button *ngIf="!editable" (click)="editable = true">{{title}}</button>
    <input *ngIf="editable" (blur)="editTitle()" [(ngModel)]="title">
  `,
})
export class EditableButtonComponent {

  @Input() title: string;
  @Output() titleChange = new EventEmitter<string>();

  editable= false;

  editTitle() {
    this.editable = false;
    this.titleChange.emit(this.title);
  }
}

然后您的模板将如下所示:

<editable-button *ngFor="let name of students; let index=index" [(title)]="students[index]"></editable-button>

注意我使用元素的索引代替它的引用。在这里你可以看到一个解释:https://github.com/angular/angular/issues/10423

在这里使用程式化的Plunker示例:https://plnkr.co/edit/eia5PYp3Z5F6WRcWpMeA?p=preview

答案 1 :(得分:2)

我不确定你的错误在哪里。这是我编写此组件的简单方法。

https://plnkr.co/edit/DpOzFIEeRZ05n64mWnvL

  @Component({
    selector: 'my-app',
    template: `
      <div>
        here is value = {{value}}
        <button [attr.contenteditable]="contenteditable" #el
             (click)="open(el)" 
             (blur)="close(el)" 
            (keyup.enter)="close(el)">{{value}}</button>
      </div>
    `,
  })
  export class App {
    value ="aaa";
    contenteditable = false;

    constructor() {
    }
    open(el) {
      this.contenteditable = true;
      setTimeout(()=>el.focus());
    }
    close(el) {
      this.contenteditable = false;
      this.value = el.innerText;
    }
  }