web-dev-qa-db-fra.com

Angular 2 contenteditable

Dans Angular 2, comment puis-je créer une liaison de données bidirectionnelle avec un div contenteditable?

<div class="editable" contenteditable="true">
    <h1>Text Field</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In pharetra felis in sem porta feugiat.</p>
 </div>
21
Codrut Tapu

J'ai adapté la réponse d'Isetty à la version finale d'Angular 2.0, désormais disponible. En plus de travailler avec la version finale, j'ai également ajouté un événement keyup et utilisé textContent plutôt que innerText, parce que cela convient mieux à mon application. Vous voudrez peut-être changer ces choses.

import {Directive, ElementRef, Input, Output, EventEmitter, OnChanges} from "@angular/core";

@Directive({
    selector: '[contenteditableModel]',
    Host: {
        '(blur)': 'onEdit()',
        '(keyup)': 'onEdit()'
    }
})

export class ContentEditableDirective implements OnChanges {
    @Input('contenteditableModel') model: any;
    @Output('contenteditableModelChange') update = new EventEmitter();

    constructor(
        private elementRef: ElementRef
    ) {
        console.log('ContentEditableDirective.constructor');
    }

    ngOnChanges(changes) {
        console.log('ContentEditableDirective.ngOnChanges');
        console.log(changes);
        if (changes.model.isFirstChange())
            this.refreshView();
    }

    onEdit() {
        console.log('ContentEditableDirective.onEdit');
        var value = this.elementRef.nativeElement.innerText
        this.update.emit(value)
    }

    private refreshView() {
        console.log('ContentEditableDirective.refreshView');
        this.elementRef.nativeElement.textContent = this.model
    }
}
16
David

S'il vous plaît se référer ce code. Cela fonctionnera vous je pense.

app.ts

@Component({
    selector: 'test-component'
})
@View({
    directives: [ContenteditableModel]
    template: `
        <h1 contenteditable="true" [(contenteditableModel)]="someObj.someProperty"></h1>
        {{someObj | json}}
    `
})
export class TestCmp {
    someObj = {someProperty: "startValue"}
}

contenteditableModel.ts:

import {Directive, ElementRef, Input, Output} from "angular2/core";
import {EventEmitter} from "angular2/src/facade/async";
import {OnChanges} from "angular2/core";
import {isPropertyUpdated} from "angular2/src/common/forms/directives/shared";

@Directive({
    selector: '[contenteditableModel]',
    Host: {
        '(blur)': 'onBlur()'
    }
})
export class ContenteditableModel implements OnChanges {
    @Input('contenteditableModel') model: any;
    @Output('contenteditableModelChange') update = new EventEmitter();

    private lastViewModel: any;


    constructor(private elRef: ElementRef) {
    }

    ngOnChanges(changes) {
        if (isPropertyUpdated(changes, this.lastViewModel)) {
            this.lastViewModel = this.model
            this.refreshView()
        }
    }

    onBlur() {
        var value = this.elRef.nativeElement.innerText
        this.lastViewModel = value
        this.update.emit(value)
    }

    private refreshView() {
        this.elRef.nativeElement.innerText = this.model
    }
}

Pour les entrées supplémentaires, j'ai trouvé un lien pour vous . https://www.namekdev.net/2016/01/two-way-binding-to-contenteditable-element-in-angular-2/

1

Pour fonctionner correctement, il est nécessaire de mettre en œuvre ControlValueAccessor pour la directive contenteditable. Voir ma solution: ng-contenteditable .

1
ktretyak

in angular 2 [(ngModel)] utilisé pour la liaison de données bidirectionnelle.

la réponse de votre question est déjà ici Comment utiliser [(ngModel)] sur le contenu de div dans angular2? jetez-y un coup d’œil et dites-moi si cela fonctionne pour vous ou non.

1
Vinay Pandya