3

the component i have is an autocompleter. however it is located inside a fixed height div and the results div needs to be parented to the body and positioned to display correctly. What would be the proper way to do this in angular2?

@Component({
    selector: 'autocomplete',
    template: `
        <div class="container" >
            <div>
              <input id="search" type="text" class="validate filter-input" [(ngModel)]=query (keyup)="filter()">
            </div>
            <div *ngIf="filteredList.length > 0">
                <ul *ngFor="let item of filteredList" >
                    <li >
                        <a (click)="select(item)">{{item}}</a>
                    </li>
                </ul>
            </div>
        </div>`,
})
export class AutocompleteComponent {
    private items: string[];
    public query: string;
    public filteredList: string[];
    public elementRef: ElementRef;

    constructor(element: ElementRef) {
        this.items = ['foo', 'bar', 'baz'];
        this.filteredList = [];
        this.query = '';
        this.elementRef = element;
    }
    filter() {
        if (this.query !== '') {
            this.filteredList = this.items.filter(function(item) {
                return item.toLowerCase().indexOf(this.query.toLowerCase()) > -1;
            }.bind(this));
        }
        else {
            this.filteredList = [];
        }
    }
}
Brett
  • 322
  • 3
  • 15

3 Answers3

2

I haven't found a way that a component can add elements to the parent level, so I suggest the following (which worked for me):

You should move the results div to a separate component with body as parent as you suggest. To control this component from your original component you can use the ngOnInit and ngOnDestroy lifecycle hooks to toggle presence of your autocomplete component to the results div component. Use a singleton service (provided by your app module) to store the state of the presence of the autocomplete component.

Peter Salomonsen
  • 5,525
  • 2
  • 24
  • 38
  • Thank you. A friend tipped me to use 'body' as the selector and that prompted me to follow the same logic as you described with using the results as a separate component. – Brett Aug 22 '16 at 17:28
2

You can move component html in constructor of AutocompleteComponent wherever you want

constructor(){
 document.querySelector('body').appendChild(elementRef.nativeElement);
            }

But you have to remove component html when component destroy i.e in ngOnDestroy() function

ngOnDestroy(){
 document.querySelector('body').removeChild(elementRef.nativeElement); 
}
Saurabh Ahuja
  • 473
  • 3
  • 13
0

You can bootstrap multiple Angular applications in one page and share a service to be able to communicate.

See How to dynamically create bootstrap modals as Angular2 components? for an example. The code example is not yet updated to RC.5.

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567