[英]Generating child components in angular2 with NgFor does not work
I'm using angular2 alpha 37. 我正在使用angular2 alpha 37。
I've defined a <map>
component and a <marker>
component (child of <map>
). 我已经定义了一个<map>
组件和一个<marker>
组件( <map>
子组件)。 The <map>
component has a array data member which contains a list of marker coordinates. <map>
组件有一个数组数据成员,它包含一个标记坐标列表。 The <map>
view should display all markers in the array <map>
视图应显示数组中的所有标记
When defining the <map>
view as follows (explicitly listing components for all array members): 在定义<map>
视图时,如下所示(显式列出所有数组成员的组件):
@View({
template:`
<marker [model]="markers[0]"></marker>
<marker [model]="markers[1]"></marker>
`,
directives:[Marker]
})
The <marker>
components are updated whenever the corresponding array member changes. 只要相应的数组成员发生更改,就会更新<marker>
组件。 This is desired behaviour. 这是期望的行为。
When defining the <map>
view as follows (using NgFor
): 在定义<map>
视图时,如下所示(使用NgFor
):
@View({
template: '<marker *ng-for="#m of markers" [model]="m"></marker>',
directives:[Marker,NgFor]
})
a new marker is created whenever the array members change, which is not desirable. 每当阵列成员改变时,都会创建一个新标记,这是不可取的。
Needles to say I would like to use the NgFor
method. Needles说我想使用NgFor
方法。
I've no clue what is going on. 我不知道发生了什么事。 How can I use NgFor
but avoid that new <marker>
instances are created whenever the individual markers update? 我如何使用NgFor
但是避免在单个标记更新时创建新的<marker>
实例?
Split the list ngFor
iterates over from the model data. 拆分列表ngFor
从模型数据迭代。
This is Dart code but shouldn't be hard to translate to TS 这是Dart代码,但不应该很难转换为TS
import 'dart:math' show Random;
import 'package:angular2/angular2.dart';
@Component(
selector: 'app-element',
template: '''
<h3>app-element</h3>
<map></map>
''',
directives: const [MapComponent])
class AppElement {}
@Component(selector: 'map',
template: '''
<button (click)="changeValue()">Change value</button>
<marker *ngFor="let m of markersIndexes" [model]="markers[m]"></marker>
<!-- use `markers[m]` to assign a model but `markersIndexes` for `*ng-for` -->
''',
directives: const [MarkerComponent, NgFor])
class MapComponent {
MapComponent() {
markers = <Marker>[
new Marker('m0', 0),
new Marker('m1', 1),
new Marker('m2', 2),
new Marker('m3', 3)
];
markersIndexes = new List<int>.generate(markers.length, (int index) => index);
}
List<Marker> markers; // model to pass to <marker>
List<int> markersIndexes; // indexes used by *ng-for
// when markers are added or removed markersIndexes need to by updated of course
// Update random marker item with random position value
Random _rnd = new Random();
void changeValue() {
int idx = _rnd.nextInt(3);
markers[idx].position = _rnd.nextInt(100);
}
}
@Component(
selector: 'marker',
template: '''
<h3>marker</h3>
<div>name: {{model.name}} pos: {{model.position}} created: {{createdAt}}</div>
''',
styles: const [
'''
:host {
display: block;
border: 1px solid green;
}
'''
])
class MarkerComponent implements OnInit {
@Input() Marker model;
String createdAt;
MarkerComponent() {
createdAt = new DateTime.now().toString();
}
void ngOnInit() {
print(model);
}
}
// Marker model
class Marker {
String name;
int position;
Marker(this.name, this.position);
@override
String toString() => 'Marker: $name - $position';
}
try this 试试这个
@View({
template:"<marker *ng-for="#m of markers" [model]="m">{{m}}</marker>",
directives:[Marker,NgFor]
})
I saw that you use the alpha37
version which remains an alpha version and you can have some bugs... I made some tests using the beta0
version and it seems to work as expected. 我看到你使用alpha37
版本仍然是alpha版本,你可以有一些bug ...我使用beta0
版本进行了一些测试,它似乎按预期工作。 So I would recommend you to upgrade to this version... We expect beta versions to be more stable ;-) 所以我建议你升级到这个版本......我们希望beta版本更稳定;-)
Here is the code I used to made my test: 这是我用来测试的代码:
Main component 主要成分
@Component({ selector: 'first-app', template: ` <map></map> `, directives: [ MapComponent ] }) export class AppComponent { }
Marker
data object Marker
数据对象
class Marker { name: string; position: int; constructor(name, position) { this.name = name; this.position = position; } }
Marker
component Marker
组件
@Component({ selector: 'marker', template:` <div class="marker">Marker {{model.name}} <button (click)="update()">Update</button></div> `, directives:[MarkerComponent] }) export class MarkerComponent implements OnInit { @Input() model: Marker; constructor() { } ngOnInit() { } update() { this.model.name = this.model.name + 'a'; } }
Map
component Map
组件
@Component({ selector: 'map', template:` <marker *ngFor="#m of markers" [model]="m"></marker> <button (click)="update()">Update</button> `, directives:[MarkerComponent] }) export class MapComponent { constructor() { this.markers = [ new Marker('m0', 0), new Marker('m1', 1), new Marker('m2', 2), new Marker('m3', 3) ]; } update() { this.markers[1].name = 'm1a'; } }
When I click on both update buttons, the name of the second marker is updated in the view and no additional <marker>
element appears. 当我单击两个更新按钮时,第二个标记的名称将在视图中更新,并且不会显示其他<marker>
元素。
Edit 编辑
It could be the way you update the element in the list. 它可能是您更新列表中元素的方式。 Do you override it with a new instance or update the value of an attribute for an existant instance in the list? 您是使用新实例覆盖它还是更新列表中存在的实例的属性值? In the first case, I think that you could will a new element addition in the list. 在第一种情况下,我认为您可以在列表中添加新元素。
update() {
this.markers[1]= new Marker('m1a', 1);
}
After doing some tests, this approach works as well. 在做了一些测试后,这种方法也可以。 No element added in the list. 列表中未添加任何元素。
Hope it helps you, Thierry 希望它对你有帮助,蒂埃里
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.