我正在处理一个项目App。现在,A可以将项目转移到B.我的界面很简单:要从左侧选择的成员和在右侧给予的成员列表。由于信息,外观和搜索功能的来源是相同的,我想到了创建一个我可以在这里使用的组件(以及另一个需要类似接口的组件)。这是一个现实但简化的版本:
在parent.ts中,html我有:
<div class="col-md-3">
<label>Source</label>
<app-browser></app-browser>
</div>
<div class="col-md-3">
<label>Destination</label>
<app-browser></app-browser>
</div>
AppBrowser.componenet.ts:
selected_g:number=0; //nothing selected yet.
eventSelect(){
var element=document.ElementByID('data') as HTMLSelectElement;
let value:number=+element.value;
if(value==0){
alert('Make a selection');
return false;
}
this.selected_g=value;
}
模板:
<select id="data">
<option value="0">Select One</option>
<option value="1">G1</option>
<option value="2">G2</option>
</select>
<button (click)="eventSelect()">Confirm</button>
现在的问题是:如果我在第一个(源,即我先插入的实例)中选择了一个有效选项,则第二个实例(目标)无效。也就是说,我可以选择值0并单击确认,它不会抱怨。如果第一个实例仅选择0,它会抱怨。我的印象是组件类似于类:如果我多次插入组件,每个组件都可以在自己的权限/空间中工作。但似乎只有第一个实例管理整个事情。我错了吗?
答案 0 :(得分:1)
这里有2个问题。第一个是How to reuse an angular component multiple times处提出的相同问题 - angular将只处理根组件的一个DOM元素 - 因此您不能拥有多个<app-browser>
标记。但是,如果将选择代码移动到子组件中,它就会起作用 - 请参阅此plunkr demo
第二个问题是您在模板中使用id="data"
中的select
。由于您正在尝试使用document.getElementById('data')
来获取它,因此它将始终返回它找到的第一个。这意味着如果第一个字段未被选中,那么即使您更改第二个字段,警报也将始终触发,因为第一个id
是从文档返回的第一个字段。
要解决此问题,您需要为组件的每个实例提供唯一的ID。您可以手动执行此操作,例如<my-sub [id]="xxx">
或动态生成它。
在角度1.x中,这可以通过$id
来完成 - 我不确定在2+中执行此操作的正确方法是什么 - 但是您可能会比使用例如Math.random()
以下使用Math.random()
对原始示例进行了修改:plunkr demo
最后,它可能仅适用于此实例,但重复组件的效果可以通过其他方式完成 - 例如在ngFor
或root
组件中使用sub
,如果有用,提供参数(包括id
)。