Repository: angular
Issue: [feature] Ability to clone a TemplateRef to multiple outlets at once
Labels: feature,area: core,core: content projection,core: dynamic view creation,type: use-case,feature: insufficient votes

# 🚀 Ability to clone a TemplateRef to multiple outlets at once

### Relevant Package
I could see this being a useful utility in `@angular/cdk`, but would likely require an update to `@angular/core`. I'm honestly not sure.


### Description
Essentially, I would like to have the ability to take a `TemplateRef` and inject _copies_ of it into multiple template outlets. The use case that made me aware of this limitation was trying to create a `<select>`-style form control, where consumers could put any arbitrary content into an option (not just text, but icons, images, components, etc.). When an option is selected, the Select component would _re_-project that option's content into the Select's template to indicate the currently selected option.

In case that's not clear, here's a simplified/truncated version of the solution that I attempted.

```typescript
@Component({
  selector: 'my-select',
  template: `
    <div class="selected-value">
      <ng-container *ngTemplateOutlet="selectedTemplate"></ng-container>
      <ng-container *ngIf="!selectedTemplate">{{ placeholder }}</ng-container>
    </div>
    <div class="options">
      <ng-content></ng-content>
    </div>
  `
})
export class SelectComponent implements AfterContentInit {

  @Input() placeholder = "Select an option";
  @ContentChildren(OptionComponent) options: QueryList<OptionComponent>;
  selectedTemplate: TemplateRef<null>;

  ngAfterContentInit() {
    this.options.forEach(option => {
      option.selected.subscribe(() => {
        this.selectedTemplate = option.contentTemplate;
      });
    });
  }

}

@Component({
  selector: 'my-option',
  template: `
    <ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
    <ng-template #contentTemplate>
      <ng-content></ng-content>
    </ng-template>
  `
})
export class OptionComponent {

  @Output() selected = new EventEmitter<void>();
  @ViewChild('contentTemplate') contentTemplate: TemplateRef<null>;

  @HostListener('click') onClick() {
    this.selected.emit();
  }

}
```

And here's an example usage that takes advantage of the template cloning:

```html
<label for="status">Task Status</label>
<my-select id="status" [(ngModel)]="statusValue">
  <my-option [value]="Status.Blocked">
    <my-icon icon="ban"></my-icon> Blocked
  </my-option>
  <my-option [value]="Status.Researching">
    <my-icon icon="science"></my-icon> Researching
  </my-option>
  <my-option [value]="Status.InProgress">
    <my-icon icon="ellipsis"></my-icon> In Progress
  <my-option>
  <my-option [value]="Status.Done">
    <my-icon icon="check"></my-icon> Done
  </my-option>
</my-select>
```

This works as intended, except it appears that the `TemplateRef` can only be embedded into one view container at any given time. So, when an option is selected, it appears in the SelectComponent's template outlet (🎉), but _disappears_ from the OptionComponent's template outlet (😭), leaving a blank spot in the options list.

![TemplateRef copy attempt](https://user-images.githubusercontent.com/13191586/87069082-984b5700-c1e4-11ea-8984-fa8d804fa7d7.png)


### Describe the solution you'd like
It would be great if the sample code above just worked as expected out of the box, but I can understand if that's not feasible, or if it's undesirable for some reason I'm not aware of.

I dug through some of CDK's source code, because I knew that its Drag-and-Drop feature was doing some sort of element cloning for the preview and placeholder elements, so I hoped that maybe they were making use of some Angular template/view APIs that I was unfamiliar with. Unfortunately, it looks like that feature is just using some [raw, low-level DOM manipulation](https://github.com/angular/components/blob/fb769ef421f5b73a5d88163864e89e1b834086ec/src/cdk/drag-drop/drag-ref.ts#L1316) to achieve this, which would be way overkill for my use case.

I wonder if it would be possible to add a `clone` method to the `TemplateRef` class, which would return a new `TemplateRef` that could be embedded into an additional template outlet without detaching the original?


### Describe alternatives you've considered

If I specifically wanted to enable icons in my OptionComponent, of course I could add an `@Input() icon: IconName`, and replicate that to my SelectComponent. I could make the OptionComponent's label a simple `@Input label: string` while I'm at it, instead of fiddling with the content projection at all. But I like to keep these types of core UI components as flexible as possible for a wide variety of use cases, so that when a new use case comes up that I hadn't originally anticipated, it can be accommodated without needing to make major updates to the component or [endlessly tack on configuration options](https://youtu.be/0BikjL858OQ?t=324). If there's another alternative or workaround that I haven't thought of, I would love to hear it.