Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

476
Views
¿Cómo usar [(ngModel)] en div's contenteditable en angular2?

Estoy tratando de usar ngModel para vincular de dos maneras el contenido de entrada editable de div de la siguiente manera:

 <div id="replyiput" class="btn-input" [(ngModel)]="replyContent" contenteditable="true" data-text="type..." style="outline: none;" ></div>

pero no funciona y se produce un error:

 EXCEPTION: No value accessor for '' in [ddd in PostContent@64:141] app.bundle.js:33898 ORIGINAL EXCEPTION: No value accessor for ''
over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

NgModel espera que el elemento enlazado tenga una propiedad de value , que los div no tienen. Es por eso que obtiene el error de No value accessor .

Puede configurar su propia propiedad equivalente y enlace de datos de eventos utilizando la propiedad textContent (en lugar de value ) y el evento de input :

 import {Component} from 'angular2/core'; @Component({ selector: 'my-app', template: `{{title}} <div contenteditable="true" [textContent]="model" (input)="model=$event.target.textContent"></div> <p>{{model}}` }) export class AppComponent { title = 'Angular 2 RC.4'; model = 'some text'; constructor() { console.clear(); } }

Plunker

No sé si el evento de input es compatible con todos los navegadores para contenteditable . En su lugar, siempre puede enlazar con algún evento de teclado.

over 4 years ago · Santiago Trujillo Report

0

Respuesta actualizada (2017-10-09) :

Ahora tengo el módulo ng-contenteditable . Su compatibilidad con las formas Angular.

Respuesta anterior (2017-05-11) : en mi caso, puedo hacerlo fácilmente:

 <div contenteditable="true" (input)="post.postTitle = $event.target.innerText" >{{ postTitle }}</div>

Donde post - es un objeto con propiedad postTitle .

La primera vez, después de ngOnInit() y obtener una post desde el backend, configuré this.postTitle = post.postTitle en mi componente.

over 4 years ago · Santiago Trujillo Report

0

Trabajando Plunkr aquí http://plnkr.co/edit/j9fDFc , pero el código relevante a continuación.


La vinculación y actualización manual de textContent no funcionaba para mí, no maneja los saltos de línea (en Chrome, escribir después de un salto de línea hace que el cursor vuelva al principio) pero pude hacerlo funcionar usando una directiva de modelo editable de https://www.namekdev.net/2016/01/two-way-binding-to-contenteditable-element-in-angular-2/ .

Lo ajusté para manejar texto sin formato de varias líneas (con \n s, no <br> s) usando white-space: pre-wrap , y lo actualicé para usar keyup en lugar de blur . Tenga en cuenta que algunas soluciones a este problema usan el evento de input que aún no es compatible con IE o Edge en elementos contenteditable .

Aquí está el código:

Directiva:

 import {Directive, ElementRef, Input, Output, EventEmitter, SimpleChanges} from 'angular2/core'; @Directive({ selector: '[contenteditableModel]', host: { '(keyup)': 'onKeyup()' } }) export class ContenteditableModel { @Input('contenteditableModel') model: string; @Output('contenteditableModelChange') update = new EventEmitter(); /** * By updating this property on keyup, and checking against it during * ngOnChanges, we can rule out change events fired by our own onKeyup. * Ideally we would not have to check against the whole string on every * change, could possibly store a flag during onKeyup and test against that * flag in ngOnChanges, but implementation details of Angular change detection * cycle might make this not work in some edge cases? */ private lastViewModel: string; constructor(private elRef: ElementRef) { } ngOnChanges(changes: SimpleChanges) { if (changes['model'] && changes['model'].currentValue !== this.lastViewModel) { this.lastViewModel = this.model; this.refreshView(); } } /** This should probably be debounced. */ onKeyup() { var value = this.elRef.nativeElement.innerText; this.lastViewModel = value; this.update.emit(value); } private refreshView() { this.elRef.nativeElement.innerText = this.model } }

Uso:

 import {Component} from 'angular2/core' import {ContenteditableModel} from './contenteditable-model' @Component({ selector: 'my-app', providers: [], directives: [ContenteditableModel], styles: [ `div { white-space: pre-wrap; /* just for looks: */ border: 1px solid coral; width: 200px; min-height: 100px; margin-bottom: 20px; }` ], template: ` <b>contenteditable:</b> <div contenteditable="true" [(contenteditableModel)]="text"></div> <b>Output:</b> <div>{{text}}</div> <b>Input:</b><br> <button (click)="text='Success!'">Set model to "Success!"</button> ` }) export class App { text: string; constructor() { this.text = "This works\nwith multiple\n\nlines" } }

Solo probado en Chrome y FF en Linux hasta ahora.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!