ВОПРОС
Я хочу создать компонент с редактируемой областью.Редактирование доступно двумя способами:
- Пользователь сначала нажимает на область и вводит что-то
- Пользователь дважды щелкает по области
обе функции не активируютсяt работает как положено.
В первом случае область становится редактируемой после щелчка, но если нажать клавишу, содержимое становится пустым, но без клавиши / символа.Код:
@HostListener('window:keydown', ['$event'])
onWindowKeydown($event) {
// ... other code
// empty the content
this.contentWrapper.nativeElement.innerHTML = ''; // works
// set the focus
this.contentWrapper.nativeElement.focus(); // works
// re-dispatch the keydown event for inser the character pressed
this.contentWrapper.nativeElement.dispatchEvent($event); // doesn't works!
}
Во втором случае после двойного щелчка компонент становится редактируемым, но при нажатии клавиши содержимое не обновляется.Код:
onDblClick($event) {
// ... othe code
this.allowEdit = true;
}
как это исправить?
WORKING DEMO
см. https://stackblitz.com/edit/angular-xwxmv2
FULLКОД
app.component.ts
import {
Component,
Input,
OnInit,
OnDestroy,
ViewChild,
ElementRef,
AfterContentInit,
OnChanges,
SimpleChanges,
SimpleChange,
HostListener
} from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
@ViewChild('contentWrapper') contentWrapper: ElementRef;
private allowEdit: boolean;
private isSelected: boolean;
private editable: boolean;
constructor() {
this.allowEdit = false;
this.isSelected = false;
this.editable = true;
}
onClick($event) {
this.isSelected = true;
}
onDblClick($event) {
this.isSelected = true;
if ( this.editable ) {
this.allowEdit = true;
}
}
onBlur($event) {
this.isSelected = false;
if ( this.editable ) {
this.allowEdit = false;
}
}
@HostListener('window:keydown', ['$event'])
onWindowKeydown($event) {
// if component is selected...
if ( this.isSelected ) {
// and is editable...
if ( this.editable ) {
// and edit is allowed...
if ( !this.allowEdit ) {
this.allowEdit = true;
setTimeout(() => {
this.contentWrapper.nativeElement.innerHTML = '';
this.contentWrapper.nativeElement.focus();
this.contentWrapper.nativeElement.dispatchEvent($event);
}, 5);
}
}
}
}
styleObject(): Object {
if ( this.isSelected ) {
return {
borderColor: 'red',
borderStyle: 'dashed',
borderWidth: '2px'
};
}
return {
borderColor: 'transparent',
borderStyle: 'dashed',
borderWidth: '2px'
};
}
}
app.component.html
<div class="warapper">
<div class="editable" [ngStyle]="styleObject()" [attr.contenteditable]="allowEdit" (click)="onClick($event)" (dblclick)="onDblClick($event)" (blur)="onBlur($event)" #contentWrapper>
Click here for select and press any key or double click here for edit this content
</div>
</div>
app.component.css
.warapper .editable {
border: 'none';
outline: none;
display: block;
min-height: 15px;
background: lightgrey;
}
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }