AngularDart:在结构指令中使用模板输入变量

时间:2018-12-28 12:26:33

标签: angular-directive angular-dart

我正在学习AngularDart。一切进展顺利。但是我受制于结构指令:我无法弄清楚如何使用模板输入变量来实现自己的结构指令。

我多次阅读了这份文档:Structural Directives

而且,尽管下面的材料涉及AngularJS,但我阅读了以下问题/文档:

据说,从微语法声明let v=value”开始,Angular创建了模板变量“ let-v”。但是,我不能在模板中使用名称“ let-v”,因为“ let-v”不是变量的有效名称。

顺便说一句,如果您查看here指令ngFor的说明:

<div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackByHeroId"
     [class.odd]="odd">
  ({{i}}) {{hero.name}}
</div>

<template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd"
          [ngForTrackBy]="trackByHeroId">
  <div [class.odd]="odd">({{i}}) {{hero.name}}</div>
</template>

您会看到在模板内部,模板输入变量i被称为i(不是let-i):

<div [class.odd]="odd">({{i}}) {{hero.name}}</div>

我在结构指令的Dart代码中尝试了很多项。但是什么都行不通。

我读了the source code for the directive NgFor。这里可能有一些有趣的东西:

  viewRef.setLocal('first', identical(i, 0));
  viewRef.setLocal('last', identical(i, len - 1));
  viewRef.setLocal('index', i);
  viewRef.setLocal('count', len);

但是,我尝试没有成功。

这是我写的简单代码:

文件:lib/src/directive_my_dummy.dart

import 'package:angular/angular.dart';

@Directive(
    selector: '[myDummy]'
)

class MyDummyDirective implements OnInit {
  TemplateRef _templateRef;
  ViewContainerRef _viewContainer;

  MyDummyDirective(TemplateRef templateRef, ViewContainerRef viewContainer) {
    _templateRef = templateRef;
    _viewContainer = viewContainer;
  }

  @Input('let-d')
  List<int> d;

  void ngOnInit() {
    print("One instance of MyDummyDirective is instantiated.");
    EmbeddedViewRef vr = _viewContainer.createEmbeddedView(_templateRef);
    vr.setLocal('d', [1,2,3]);
    print(d.toString());
  }
}

文件:lib/app_component.html

<div *myDummy="let d=data">
    This is a dummy test. {{d.toString()}}
</div>

<div *myDummy="let d=[1,2,3]">
    This is a dummy test. {{d.toString()}}
</div>

<div *myDummy="let d=getData()">
</div>

<div *myDummy="let d=[1,2,3]; let name='Toto'"></div>

完整代码可在here中找到。

您能告诉我一个基本的例子来说明模板输入变量的用法吗?

1 个答案:

答案 0 :(得分:0)

首先,我们将两个实体称为“模板”:

  • 组件模板。
  • (结构)指令模板。

输入模板变量”一词指的是(结构)指令模板。

我认为最好使用名称“ 输入指令模板变量”。

我将使用名称“ 输入指令模板变量”代替“输入模板变量”。

输入指令模板变量的作用是配置(结构性)指令模板

输入指令模板变量的值从哪里来?

答案是:输入指令模板变量的值在指令实例内分配。您不能直接在组件模板中定义 input指令模板变量的值。例如,下面的代码<div *myDummy="let d=10">将值10分配给变量d

输入指令模板变量的值是从指令实例内部分配的。例如:

TemplateRef _templateRef;
ViewContainerRef _viewContainer;
// ...
_viewContainer.createEmbeddedView(_templateRef);
_viewContainer.get(0).setLocal('data', 'MyDummyDirective.data');

然后在组件模板中编写:

<div *myDummy="let d=data">

我举一个简单的例子:

lib/src/directive_my_dummy.dart

@Directive(
    selector: '[myDummy]'
)
class MyDummyDirective implements OnInit {
  TemplateRef _templateRef;
  ViewContainerRef _viewContainer;

  @Input('myDummyVariable')
  String variable;

  MyDummyDirective(this._templateRef, this._viewContainer);

  void ngOnInit() {
    // WARNING: the property "variable" has no value assigned within the constructor.
    _viewContainer.createEmbeddedView(_templateRef);
    _viewContainer.get(0).setLocal('data', 'MyDummyDirective.data');
    print('MyDummyDirective.variable = ${variable}');
    _viewContainer.get(0).setLocal('var', 'This is ' + variable);
  }
}

lib/app_component.html

<div *myDummy="let d=data; variable:'value from the lib/app_component.html'; let v=var">
        <p>This is a dummy directive.</p>
        <ul>
            <li><b>d</b>=<code>{{d.toString()}}</code></li>
            <li><b>data</b>=<code>{{data}}</code> (makes reference to the instance of AppComponent)</li>
            <li><b>v</b>=<code>{{v}}</code></li>
        </ul>
</div>

lib/app_component.dart

import 'package:angular/angular.dart';
import 'package:myapp/src/directive_my_dummy.dart';

@Component(
    selector: 'app-component',
    templateUrl: 'app_component.html',
    directives: [MyDummyDirective],
)
class AppComponent {
    List<int> getData() => [100, 200, 300];
    String data = 'AppComponent.data';
}

结果:

This is a dummy directive.

<ul>
    <li>d=MyDummyDirective.data</li>
    <li>data=AppComponent.data (makes reference to the instance of AppComponent)</li>
    <li>v=This is value from the lib/app_component.html</li>
</ul>

编辑:

As a picture often speaks better than words...