首页 > 解决方案 > Angular:通过双击或键入anykey可编辑内容的div

问题描述

问题

我想制作一个具有可编辑区域的组件。通过两种方式启用编辑:

  1. 用户首先单击该区域并输入一些内容
  2. 用户双击该区域

这两个功能都没有按预期工作。

在第一种情况下,该区域在单击后变为可编辑,但如果按一个键,则内容变为空但没有键/字符。编码:

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

标签: javascriptangular

解决方案


推荐阅读