Using a component more than once in a single parent component

半城伤御伤魂 提交于 2019-12-24 19:08:58

问题


I am working on an items App. Now, A can transfer items to B. My interface is simple: list of members to chose from as source on left and to whom to give on the right. Since the source of the information, appearance and search functionality is the same, I thought of creating one component that I can use here (and in another component that requires similar interface). Here is a realistic but simplified version:

In parent.ts, html I have:

<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>

The 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;
}

the template:

<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>

Now the problem is: if I select a valid option in the first (source i.e. the instance I inserted first), the second instance (destination) has no effect. That is, I can select value 0 and click Confirm and it wouldn't complain. It would complain if the first instance has selected 0 only. I was under the impression components are like classes: if I insert the components multiple times, each one would work in its own right/space. But it appears only the first instance manages the whole thing. Am I mistaken?


回答1:


There are 2 issues here. The first is the same issue raised at How to reuse an angular component multiple times - angular will process only one DOM element for the root component - so you can't have more than one <app-browser> tag. However it works if you move the select code into a sub-component - see this plunkr demo

The 2nd issue is that you are using id="data" in select in the template. Since you are then trying to fetch it using document.getElementById('data') it will always return the first one it finds. This means that if the first field is unselected, then even if you change the 2nd one the alert will always fire since the first id is the first one returned from the document.

To fix this you need a unique id for each instance of the component. You could do this manually, e.g. <my-sub [id]="xxx"> or posisbly generate it dynamically.

In angular 1.x this could be done with $id - I'm not sure what the correct way to do this in 2+ is - but you could do worse than use e.g. Math.random() Here's a modification of the original example using Math.random(): plunkr demo

Finally, it might only be applicable to this instance, but the effect of repeating the component could be done in other ways - for example using ngFor in the root or sub component, providing arguments (including an id) if useful.



来源:https://stackoverflow.com/questions/48370756/using-a-component-more-than-once-in-a-single-parent-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!