2016-08-18 2 views
10

В Angular 2 как я могу сделать привязку данных с двумя способами с помощью contenteditable div?Угловой 2 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> 
+0

Возможный дубликат [Как использовать \ [(ngModel) \] на div, доступном для контента в угловом2?] (Http://stackoverflow.com/questions/35378087/how-to-use-ngmodel-on-divs-contenteditable -in-angular2) – tobek

ответ

0

См. Этот код. Он будет работать, я думаю.

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

Для дополнительных входов я нашел ссылку для вас. https://www.namekdev.net/2016/01/two-way-binding-to-contenteditable-element-in-angular-2/

+0

Спасибо! Вы работаете с кодом, но у меня две проблемы: -my someObj.someProperty содержит много html (10-15 тегов). После того, как я что-то изменить весь HTML становится простой текст -в редактировать текст я использовать текстовый редактор - Summernote Вот часть моего объекта JSon: [ { «тусклым»: 4, «идентификатор» : 1, "moduleType": { "идентификатор": 1, "имя": "текст-модуль", "содержание": "

Text Field 1

Lorem Ipsum боль сидеть Амет, consectetur adipiscing Элит В. phareis felis in sem porta feugiat.

" } }, МодульType.conten t это то, что я хочу отредактировать –

+0

ok. я буду следить за ним. :) –

0

в угловом 2 [(ngModel)] используется для двусторонней передачи данных.

ответ на ваш вопрос уже здесь How to use [(ngModel)] on div's contenteditable in angular2? проверьте это и сообщите мне, если он работает на вас или нет.

11

Я адаптировал ответ Isetty для работы с версией версии Angular 2.0, теперь она доступна. Помимо работы с версией выпуска, я также добавил событие keyup и использовал textContent, а не innerText, потому что это лучше подходит для моего приложения. Вы можете изменить это.

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

Дэвид, случайно, у вас есть плункер с рабочей версией? –

+2

Я попытался выполнить совместимую с TSLint совместимую версию, но у меня нет решения для исправления no-input-rename и no-output-rename. См. Https://gist.github.com/zamber/f2d15337c245285d498d9a6b94de3117 Я также добавил несколько приятных вещей, например, enter to accept, esc для отмены и испускания при полном изменении значения, а не для каждого нажатия клавиши. – zamber

-1

Угловая 4/2 (Машинопись) с динамическим редактируемые:

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

} 
0

Для правильной работы, необходимо реализовать ControlValueAccessor для директивы contenteditable. См. Мое решение: ng-contenteditable.

Смежные вопросы