Angular 4 - 如何从ViewContainerRef

时间:2017-11-18 09:01:05

标签: angular

我想要完成的是什么: 当用户在enter元素内按<p>时,会在其后添加新的<p>元素。 用户可能会在第5个视图中按下ENTER键...

我是如何尝试的?:在<p>元素上,有一个keyPress侦听器。当按下enter键时,我试图获取当前元素的索引并在之后添加一个,如下所示:

let dom_view = e.currentTarget
let index = this.richtextbox.indexOf(dom_view);

this.richtextbox.insert(this.p_dom.createEmbeddedView(null),index+1);

我面临的问题:索引始终为-1,因为容器未识别e.currentTarget(与e.target相同)!获取索引的正确方法是什么?

我的组件代码

import {
  AfterViewInit, Component, ViewChild, ViewContainerRef
} from '@angular/core';

@Component({
  selector: 'app-editor',
  templateUrl: './editor.component.html',
  styleUrls: ['./editor.component.css']

})
export class EditorComponent  implements AfterViewInit {

  @ViewChild('richtextbox', {read: ViewContainerRef}) richtextbox: ViewContainerRef;
  @ViewChild('p_dom') p_dom;

  ngAfterViewInit(): void {
    // insert a p element
    let view1 = this.p_dom.createEmbeddedView(null)
    this.richtextbox.insert(view1);
  }
  editor_keypress(e) {
    let dom_view = e.currentTarget

    if (e.key === 'Enter') {
      let index = this.richtextbox.indexOf(dom_view);
      // notice that index is the index of the view that the user pressed
      // the enter on. there can be 1000 views... and i want to add the new 
      // view right after the one that the user pressed the enter on
      console.log('index = ', index)

      this.richtextbox.insert(this.p_dom.createEmbeddedView(null),index+1);
    }
  }
}

HTML上下文是:

<ng-container #richtextbox>
</ng-container>

<ng-template #p_dom>
  <p contenteditable="true" (keypress)="editor_keypress($event)">I am editable test message</p>
</ng-template>

更新

我最终使用Renderer2来操纵doms。 ViewRef的问题在于我无法创建具有封闭视图的侦听器,如Bougarfaoi的答案所描述的那样。如果你想查看代码,这里是github代码的link

1 个答案:

答案 0 :(得分:1)

this.richtextbox.indexOf中传递的值必须是ViewRef类型,并且您将HTMLElement传递给它,所以这是解决方案:

<强> Demo

import { AfterViewInit, Component, ViewChild, ViewContainerRef } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  @ViewChild('richtextbox', {read: ViewContainerRef}) richtextbox: ViewContainerRef;
  @ViewChild('p_dom') p_dom;
   view1
  ngAfterViewInit(): void {
    // insert a p element
    this.view1 = this.p_dom.createEmbeddedView(null)
    this.richtextbox.insert(this.view1);
  }
  editor_keypress(e) {
    let dom = e.currentTarget


    if (e.key === 'Enter') {
      let index = this.richtextbox.indexOf(this.view1);
      console.log(this.richtextbox);
      console.log('dom = ', dom)
      console.log('index = ', index)

      this.richtextbox.insert(this.p_dom.createEmbeddedView(null),index+1);
    }
  }
}