我正在学习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中找到。
您能告诉我一个基本的例子来说明模板输入变量的用法吗?
答案 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);
}
}
<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>
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>
编辑: