问题
我要制作一个具有可编辑区域的组件。可以通过两种方式启用编辑:
两个功能均无法正常工作。
在第一种情况下,单击后该区域变为可编辑的,但是如果按某个键,则内容将变为空白,但没有键/字符。代码:
@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;
}
如何解决?
工作演示
请参阅https://stackblitz.com/edit/angular-xwxmv2
完整代码
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 { }