2

I am trying to figure out if in angular you can reuse a snippet of html across multiple angular components and locations.

What i am trying to solve is, on my drop down lists (whose information comes from outside my system), i wish to add a empty value and a placeholder to them if not selected, as follows :

<select class="custom-select" [(ngModel)]="modelValue">
    <option value="">PlaceholderText</option>
    <option value="null" hidden disabled>PlaceholderText</option>
    <option value ="undefined" disabled hidden >PlaceholderText</option>
    <option *ngFor="let option of option()" [value]="option.code">
        {{optionn.desc}}
    </option>

The code above works and achieves the expected result, what i am looking for is for a way to make those 3 first options reusable across my whole application in all the dropdown lists where i need it.

Tried with a super basic component with those first 3 options in the template but since it renders the component wrapper tag it does not work.

With templates i belive i would have to define it in each components base tempalte where i need it.

Is there any way i can define a ngTemplate,ngContainer or something else with that html snippet (the first 3 options) and reuse it across my application ?

Thank you

Amgg
  • 117
  • 9

1 Answers1

2

Make that selecta component, that's what components are for.

It can take a list of options to populate inside the select after the first 3 default ones, plus the modelValue being used (use modelValueChange as well so that it can be both input and output), also you can have a default Placholder Text but optionaly use a different one depending on your component.

something like

@Component({
    selector: 'my-select',
    template: `
        <select class="custom-select" [(ngModel)]="modelValue">
            <option value="">{{PlaceholderText}}</option>
            <option value="null" hidden disabled>{{PlaceholderText}}</option>
            <option value ="undefined" disabled hidden >{{PlaceholderText}}</option>
            <option *ngFor="let option of options" [value]="option.code">
                {{optionn.desc}}
            </option>
        </select>
    `
})
export class MySelectComponent implements  OnInit{
    @Input() options: MyOptionsModel[] = [];
    @Input() placeholderText: string = 'Placeholder Text';
    @Input() modelValue: any;
    @Output() modelValueChange = new EventEmitter<any>();

    constructor() {}

    ngOnInit(){
     // whatever
    }
}

then in any component

<my-select [options]="myOptions" [(modelValue)]="myModelValue"></my-select>
FabioG
  • 2,936
  • 3
  • 31
  • 50
  • Thank you, might use this aproach instead of the slight hack i found in this awnser : https://stackoverflow.com/a/56887630/12669427 . Only problem i see with your approach is that there is a potential for it to have alot of input parameters if you need to provide more directives/parameters for the select, but i belive there might be a way arround that by making it attribute component. Thank you – Amgg Apr 22 '20 at 20:31
  • @Amgg you're very welcome. I understand what you mean about having multiple params, usually what I do to avoid that is to have some sort of a 'config' model and an input param that accepts an object of that type, being that you can decide what parameters inside the configs are mandatory or optional, and even have defaults. – FabioG Apr 23 '20 at 07:03