如何在 contenteditable 元素中使用 ngControl? [英] How can I use ngControl in contenteditable element?

查看:33
本文介绍了如何在 contenteditable 元素中使用 ngControl?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在 contenteditable 元素中使用 ngControl?例如,我想要:

<td contenteditable="true" [ngControl]="row.number + column.number"></td>

绑定(?)它到模型驱动的表单"(表).我使用 formBuilder 基于从服务器检索的架构创建了他.
目前我认为这不起作用,因为 (和其他)元素没有属性 value.那么,可以重载一些方法来使用 textContent 属性吗?或者存在其他方式来做到这一点?

谢谢.

解决方案

为了能够在 Angular2 和控件中使用 contenteditable 元素,您需要创建一个适用于 的自定义指令contenteditable 该指令必须与 ngModel/ngForm 兼容,以便您可以使用 ngFormngFormControl 等指令.在内部,此指令将注册一个自定义的 `Value

这是一个可能的实现:

const CUSTOM_VALUE_ACCESSOR = CONST_EXPR(new Provider(NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => ContenteditableAccessor), multi: true}));@指示({选择器:'[contenteditable]',主持人:{'(模糊)':'onBlur($event)'},提供者:[CUSTOM_VALUE_ACCESSOR]})导出类 ContenteditableAccessor 实现 ControlValueAccessor {onChange = (_) =>{};onTouched = () =>{};构造函数(私有 eltRef:ElementRef){}ngOnInit() {this.onChange(this.eltRef.nativeElement.innerText);}writeValue(value: any): void {如果(值!=空){this.eltRef.nativeElement.innerText = 值;}}onBlur(事件){this.onChange(this.eltRef.nativeElement.innerText);}registerOnChange(fn: (_: any) => void): void { this.onChange = fn;}registerOnTouched(fn: () => void): void { this.onTouched = fn;}}

您将能够在组件中以这种方式使用此指令:

@Component({选择器:'我的应用',模板:`<div><表格><label>名字:</label><span contenteditable="true" [ngFormControl]="testCtrl">一些值</span></表单><div>名字:{{testCtrl.value}}<br/>名字:{{testCtrl.valid}}<br/>

<div (click)="updateConditions()">更新条件</div>

`,指令:[ FORM_DIRECTIVES, ContenteditableAccessor ]})导出类 AppComponent {构造函数(){this.testCtrl = new Control();}}

这里是对应的plunkr:https://plnkr.co/edit/JbjXIa?p=预览.

关于ngForm/ngModel兼容的自定义组件的更多细节,你可以在NgModel-compatible component"部分查看这篇文章:

How can I use ngControl in contenteditable element? For example, I want:

<!-- *ngFor over rows and columns in table -->
<td contenteditable="true" [ngControl]="row.number + column.number"></td>

With binding (?) it to model-driven "form" (table). I create him with formBuilder based on schema, that retrieve from server.
Currently I think that doesnt work, 'cause <td> (and others) element haven't property value. Then, possible to overload some methods to work with textContent property? Or exist other way to do this?

Thank you.

解决方案

To be able to use contenteditable elements with Angular2 and controls, you need to create a custom directive that applies to the contenteditable This directive must be ngModel / ngForm compatible so you will be able to use directives like ngForm and ngFormControl. Internally this directive will register a custom `Value

Here is a possible implementation:

const CUSTOM_VALUE_ACCESSOR = CONST_EXPR(new Provider(
  NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => ContenteditableAccessor), multi: true}));

@Directive({
  selector: '[contenteditable]',
  host: {'(blur)': 'onBlur($event)'},
  providers: [CUSTOM_VALUE_ACCESSOR]
})
export class ContenteditableAccessor implements ControlValueAccessor {
  onChange = (_) => {};
  onTouched = () => {};

  constructor(private eltRef:ElementRef) {
  }

  ngOnInit() {
    this.onChange(this.eltRef.nativeElement.innerText);
  }

  writeValue(value: any): void {
    if (value!=null) {
      this.eltRef.nativeElement.innerText = value;
    }
  }

  onBlur(event) {
    this.onChange(this.eltRef.nativeElement.innerText);
  }

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

You will be able to use this directive this way in a component:

@Component({
  selector: 'my-app',
  template: `
    <div>
      <form>
        <label>First name:</label>
        <span contenteditable="true" [ngFormControl]="testCtrl">Some value</span>
      </form>
      <div>
        firstName: {{testCtrl.value}}<br/>
        firstName: {{testCtrl.valid}}<br/>
      </div>
      <div (click)="updateConditions()">Update conditions</div>
    </div>
  `,
  directives: [ FORM_DIRECTIVES, ContenteditableAccessor ]
})
export class AppComponent {
  constructor() {
    this.testCtrl = new Control();
  }
}

Here is the corresponding plunkr: https://plnkr.co/edit/JbjXIa?p=preview.

For more details about ngForm / ngModel compliant custom components, you could have a look at this article in the section "NgModel-compatible component":

这篇关于如何在 contenteditable 元素中使用 ngControl?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆