gpt4 book ai didi

具有 contentEditable div 和 ngModel 支持的 Angular 2 表单

转载 作者:太空狗 更新时间:2023-10-29 17:13:48 24 4
gpt4 key购买 nike

我正在尝试使用 Angular 2 Forms,但我不想使用 input,而是想使用可编辑的 div

这个有效:

<input type="text" [(ngModel)]="value">

但这会引发错误:

<div contentEditable="true" [(ngModel)]="value"></div>

TypeError: setting a property that has only a getter

有没有办法将 div 与 Angular Forms 一起使用?我不想使用输入或文本区域

最佳答案

不是开箱即用的..

ngModel 只能在支持它的元素上访问!

您可以创建指令或自定义输入组件。

无论如何,它必须实现这个接口(interface)ControlValueAccessor

指令:

工作演示:https://plnkr.co/edit/12vAEFf2OBS3ERu9fhwk?p=preview

import {Directive, Component, NgModule, forwardRef, ViewChild, ElementRef, HostListener, Renderer} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { FormsModule, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Directive({
selector: 'div[contentEditable]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => EditableDivDirective),
multi: true
}
]
})
export class EditableDivDirective implements ControlValueAccessor {

constructor(private _elRef: ElementRef, private _renderer: Renderer) { }

onChange() {
if (this._onChange) {
this._onChange(this._elRef.nativeElement.innerText);
}
}

@HostListener('keyup', ['$event'])
keyup(event: any) {
this.onChange();
}


// ControlValueAccessor implementation
// ====================================

private _onChange = (_) => { }; // call it if your value changed..
private _onTouched = () => { }; // call it "on blur" ..

// will be called if a values comes in via ngModule !
writeValue(val: any) {
if (!val) val = '';

this._renderer.setElementProperty(this._elRef.nativeElement, 'innerText', val);
}

registerOnChange(fn: (_: any) => void): void { this._onChange = fn; }
registerOnTouched(fn: () => void): void { this._onTouched = fn; }
}

@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<div contentEditable="true" [(ngModel)]="name">test test test</div>
</div>
`,
})
export class App {
name:string;
constructor() {
this.name = 'Angular2'
}
}

@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ App, EditableDivDirective ],
bootstrap: [ App ]
})
export class AppModule {}

组件:

查看工作演示:https://plnkr.co/edit/XMSTrWSe3gN9iwVTBukz?p=preview

import {Component, NgModule, forwardRef, ViewChild, ElementRef} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { FormsModule, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
selector: 'my-name-input',
template: `
<div>
<label>first name</label>
<div #firstName contentEditable="true" (keyup)="onChange()">{{this._firstName}}</div>
<br />
<label>last name</label><input [(ngModel)]="_lastName" (ngModelChange)="onChange()" />
</div>
`,
providers: [ // IMPORTANT !!
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MyCompleteNameInputComponent),
multi: true
}
]
})
export class MyCompleteNameInputComponent implements ControlValueAccessor {

@ViewChild('firstName') editableDiv: ElementRef;

private _firstName: string = '';
private _lastName: string = '';

onChange() {

this._firstName = this.editableDiv.nativeElement.innerText;

if (this._onChange) {
this._onChange(this._firstName + ' ' + this._lastName);
}
}


// ControlValueAccessor implementation
// ====================================

private _onChange = (_) => { }; // call it if your value changed..
private _onTouched = () => { }; // call it "on blur" ..

// will be called if a values comes in via ngModule !
writeValue(val: any) {
if (!val || !val.split) val = '';

let splitted = val.split(' ');
this._firstName = splitted[0] || '';
this._lastName = splitted[1] || '';
}

registerOnChange(fn: (_: any) => void): void { this._onChange = fn; }
registerOnTouched(fn: () => void): void { this._onTouched = fn; }
}

@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<my-name-input [(ngModel)]="name"></my-name-input>
</div>
`,
})
export class App {
name:string;
constructor() {
this.name = 'Angular2'
}
}

@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ App, MyCompleteNameInputComponent ],
bootstrap: [ App ]
})
export class AppModule {}

关于具有 contentEditable div 和 ngModel 支持的 Angular 2 表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39655336/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com