Angular 2 contenteditable

2019-01-23 03:10发布

In Angular 2 how can I make two way data binding with a contenteditable div?

<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>

5条回答
forever°为你锁心
2楼-- · 2019-01-23 03:30

To work properly, it is necessary to implement ControlValueAccessor for the directive contenteditable. See my solution: ng-contenteditable.

查看更多
看我几分像从前
3楼-- · 2019-01-23 03:40

Angular 4/2 (Typescript) with dynamic editable:

// Imports
import { Component} from '@angular/core';

@Component({
    selector: 'discussion',
    template: `                                 
    <div class="details">
        <p class="time">Wednesday 14 Nov, 2016 10.13PM</p>
        <p class="text" name="discussion" 
            [contentEditable]="editable" 
            [ngClass]="{ 'editable': editable }" 
            (blur)="uDiscussion()" 
            (click)="eDiscussion($event)" 
            (input)="discussion = $event.target.innerText" 
        >{{ discussion }}</p>
    </div>
    <div class="dropdown">
        <a href="#" data-toggle="dropdown" class="dropdown-toggle">
            <i class="fa fa-ellipsis-v"></i>
        </a>
        <ul class="dropdown-menu">
            <li><a  (click)="eDiscussion($event)" >Edit</a></li>
            <li><a  (click)="dDiscussion()" >Delete</a></li>
        </ul>
    </div>`,
    styles: [`.editable {
        white-space: pre-wrap;
        border: 1px solid coral;
        width: 200px;
        min-height: 20px;
    }`]
})

export class DiscussionComponent {

    constructor(){}

    public discussion: string = "Test string";
    public editable: boolean = false;

    dDiscussion(){
        console.log("delete");
    }

    eDiscussion(event: any){
        // on click this will set 'contentEditable' to true 
        // and add 'editable' class for styling.
        this.editable = true;
    }

    uDiscussion(event: any){
        // on blur set 'contentEditable' to false 
        // and remove class 'editable' and log new values
        this.editable = false;
        console.log("this.discussion");
        console.log(this.discussion);
    }

}
查看更多
劳资没心,怎么记你
4楼-- · 2019-01-23 03:41

I've adapted Isetty's answer to work with the release version of Angular 2.0, now it is available. Apart from working with the release version, I've also added a keyup event and used textContent rather than innerText, because that suites my application better. You may wish to change these things.

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
    }
}
查看更多
SAY GOODBYE
5楼-- · 2019-01-23 03:41

Please refer this code. It will work you i think.

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

For the extra inputs i found a link for you. https://www.namekdev.net/2016/01/two-way-binding-to-contenteditable-element-in-angular-2/

查看更多
我欲成王,谁敢阻挡
6楼-- · 2019-01-23 03:42

in angular 2 [(ngModel)] used for two way data binding.

the answer of your question is already here How to use [(ngModel)] on div's contenteditable in angular2? check this out and let me know if it is working for you or not.

查看更多
登录 后发表回答