Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2: ContenteditableModel: 2-way data binding

I am able to emit an event from the contenteditableModel directive but I am not able to receive the data ' @Input('contenteditableModel') model: any;' i keep getting undefined.

contenteditableModelChange works fine, but not contenteditableModel

The way I update my data is by updating the this.elementRef.nativeElement.textContent as I was not able to figure out how to use [innerHTML]

This directive is based on this guy code: but rebuilt for angular 2.0.

export class pageContent{
    <p
 contenteditable="true"

(contenteditableModelChange)="runthis($event)"
[contenteditableModel]="text"


></p>

    public text:any = 'ddddd';
    constructor(){}
    runthis(ev){
        this.text  = ev
            console.log('updated done ev', ev)
            console.log('text now should be ', this.text)
    }

}

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

By the way if anyone suggest to set up my own equivalent property and event databinding using the textContent property (instead of value) and the input event, I already tried it on this plunker and there is a issue that cursor on IE, Firefox and Safari gets set to 0

http://plnkr.co/edit/KCeKTPu8dJI0O1nVMPfb?p=preview

like image 392
Chris Tarasovs Avatar asked Jun 04 '17 18:06

Chris Tarasovs


People also ask

Is angular 2 support two-way data binding only?

Angular v2+ supports two-way data binding using ngModel directive and also by having getter and setter methods.

What is 2 way data binding in Angular?

Two-way binding gives components in your application a way to share data. Use two-way binding to listen for events and update values simultaneously between parent and child components.

What is one-way binding and two-way binding in Angular?

Difference between One-way & Two-way Binding This means that the flow of code is from ts file to Html file as well as from Html file to ts file. In order to achieve one-way binding, we used the property binding concept in Angular. In order to achieve a two-way binding, we will use ngModel or banana in a box syntax.

Can we do two-way binding without ngModel?

And to answer your question ... you shouldn't need ngModel here. Your binding should be handled by your use of the formControlName . And to set the value, use the above shown code.


1 Answers

I changed ngOnChanges to this :

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

Its working fine .

Plnkr: https://plnkr.co/edit/VW4IJvcv1xjtBKTglWXT?p=preview

According to docs: isFirstChange() tells us if we are assigning the value for the first time . According to your code, you want to update text only if its first time change. Which is wrong. My opinion we dont need to worry about it at all.

like image 195
Vamshi Avatar answered Oct 13 '22 10:10

Vamshi