使用模板输入变量的 Angular 2 自定义结构指令绑定不起作用 [英] Angular 2 Custom Structural Directive binding using template input variable is not working

查看:22
本文介绍了使用模板输入变量的 Angular 2 自定义结构指令绑定不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个类似于 ngFor 的自定义结构指令.当我尝试使用 <template> 元素语法使用它时,模板内的绑定正在工作,但是当我使用 * 语法时,绑定不起作用.

 <模板编辑[editOf]=值";let-val=val"><表><span>这是使用模板语法 {{val}}</span><!-- 不工作--><table *edit="let val1 of values"><span>这使用星形语法 {{val1}}</span>

这是针对此问题的 plnkr 链接.

我做错了什么?

更新:我想,现在我明白是怎么回事了.let-val 被错误地设置为用于绑定的对象的属性 val 但我需要整个对象.因此,let-val 不应在模板中分配任何值,然后我必须使用在 viewRef 中用作绑定源的对象来更新 context.$implicit.

plnkr 在这里工作.

感谢@robisim74

解决方案

试试这个:

import { ChangeDetectorRef,指示,输入,做检查,可迭代差异,IterableDiffers,模板参考,视图容器引用,EmbeddedViewRef} 来自@angular/core";@指示({选择器":[editOf]"})导出类 EditableTableDirective 实现了 DoCheck {私人收藏:任何;私有差异:IterableDiffer;private viewMap:Map= new Map();构造函数(私有 changeDetector:ChangeDetectorRef,私人差异:IterableDiffers,私有模板:TemplateRef,私有视图容器:ViewContainerRef){}@Input() 设置 editOf(coll:any){this.collection = coll;如果 (coll && !this.differ) {this.differ = this.differs.find(coll).create(this.changeDetector);}}ngDoCheck() {如果(this.differ){const 变化 = this.differ.diff(this.collection);如果(改变){changes.forEachAddedItem((change) => {const view = this.viewContainer.createEmbeddedView(this.template, change.item);view.context.$implicit = change.item;this.viewMap.set(change.item, view);});changes.forEachRemovedItem((change) => {const view = this.viewMap.get(change.item);const viewIndex = this.viewContainer.indexOf(view);this.viewContainer.remove(viewIndex);this.viewMap.delete(change.item);});}}}}

然后更正模板:

<span>这使用星型语法 {{item.val}}</span>

我关注了这篇文章:http://teropa.info/blog/2016/03/06/writing-an-angular-2-template-directive.html

I have created a custom structural directive similar to ngFor. When I try to use it using <template> element syntax, the binding inside the template is working but when I use * syntax, the binding is not working.

   <!-- working -->
    <template edit [editOf]="values" let-val="val">
      <table >
        <span>This is using template syntax {{val}}</span>
      </table>
    </template>
    
    <!-- not working -->
      <table *edit="let val1 of values">
        <span>This uses star syntax {{val1}}</span>
      </table>

Here is the plnkr link for this issue.

What am I doing wrong?

Update: I think, now I understand what is going on. The let-val is incorrectly set to a property val of object used for binding but I need the whole object. So, the let-val shouldn't be assigned with any value in the template and then I'll have to update the context.$implicit with the object used as binding source in the viewRef.

Working plnkr here.

Thanks to @robisim74

解决方案

Try this:

import {  ChangeDetectorRef,
  Directive,
  Input,
  DoCheck,
  IterableDiffer,
  IterableDiffers,
  TemplateRef,
  ViewContainerRef,
  EmbeddedViewRef} from "@angular/core";

@Directive({
  "selector":"[edit][editOf]"
})
export class EditableTableDirective implements DoCheck {

  private collection:any;
  private differ:IterableDiffer;
  private viewMap:Map<any,EmbeddedViewRef> = new Map<any,EmbeddedViewRef>();

  constructor(
    private changeDetector:ChangeDetectorRef,
              private differs:IterableDiffers,
              private template:TemplateRef,
              private viewContainer:ViewContainerRef){
  }

  @Input() set editOf(coll:any){
    this.collection = coll;
    if (coll && !this.differ) {
      this.differ = this.differs.find(coll).create(this.changeDetector);
    }
  }

  ngDoCheck() {
    if (this.differ) {
      const changes = this.differ.diff(this.collection);
      if (changes) {
        changes.forEachAddedItem((change) => {
          const view = this.viewContainer.createEmbeddedView(this.template, change.item);
          view.context.$implicit = change.item;
          this.viewMap.set(change.item, view);
        });
        changes.forEachRemovedItem((change) => {
          const view = this.viewMap.get(change.item);
          const viewIndex = this.viewContainer.indexOf(view);
          this.viewContainer.remove(viewIndex);
          this.viewMap.delete(change.item);
        });
      }
    }
  }

}

Then correct the template:

<table *edit="let item of values">
   <span>This uses star syntax {{item.val}}</span>
</table>  

I followed this article: http://teropa.info/blog/2016/03/06/writing-an-angular-2-template-directive.html

这篇关于使用模板输入变量的 Angular 2 自定义结构指令绑定不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆