How to fix broken ngModel after you have allowed content for a button?

I have the following code:

Template:

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

TypeScript

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

The problem is that as soon as I change the content with content editing, I seem to lose the binding to {{name}}, as if I have a separate button on the page:

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

The students array changes, but when I look at the button text, this is what I โ€œeditedโ€ in contenteditable and donโ€™t show Amy at all.

+4
source share
2 answers

I suggest you use ngModeland clean Angular data binding method for two reasons in the built-in components:

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

And then your template will look like this:

<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

+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;
    }
  }
+2

Source: https://habr.com/ru/post/1675945/


All Articles