title: Angular material <mat-selection-list> and <mat-list-option> across template boundaries
body: <p><strong>How to make <code>&lt;mat-list-option&gt;</code> -- declared in component <code>sub</code> -- "subscribe" to a <code>&lt;mat-selection-list&gt;</code> outside component <code>sub</code> (say, component <code>app</code>)?</strong></p>
  
  <p>(unfortunately I couldn't manage to make Stackblitz work with my corporate's proxy, so I'll put only the relevant pieces of my examples)</p>
  
  <p><strong>Example 1</strong> (working, no component <code>sub</code>)</p>
  
  <p>(app.component.html)</p>
  
  <pre class="lang-html prettyprint-override"><code>&lt;div&gt;{{selections | json}}&lt;/div&gt;
  &lt;mat-selection-list [(ngModel)]="selections"&gt;
    &lt;mat-list-option [value]="{x: 1}"&gt;x: 1&lt;/mat-list-option&gt;
    &lt;mat-list-option [value]="{x: 2}"&gt;x: 2&lt;/mat-list-option&gt;
    &lt;mat-list-option [value]="{y: 1}"&gt;y: 1&lt;/mat-list-option&gt;
    &lt;mat-list-option [value]="{y: 2}"&gt;y: 2&lt;/mat-list-option&gt;
  &lt;/mat-selection-list&gt;
  </code></pre>
  
  <p>(app.component.ts)</p>
  
  <pre class="lang-js prettyprint-override"><code>@Component({
    templateUrl: './app.component.html',
  })
  export class AppComponent {
    selections = [];
  }
  </code></pre>
  
  <p>This example works as expected. All 4 options are rendered, and their selections are reflected back in <code>selections</code> property (all options' values are javascript objects, and they are correctly inserted to/elided from the <code>selections</code> array).</p>
  
  <p><strong>Example 2</strong> (not working, component <code>sub</code> added between <code>&lt;mat-selection-list&gt;</code> and <code>&lt;mat-list-option&gt;</code>)</p>
  
  <p>(app.component.html)</p>
  
  <pre class="lang-html prettyprint-override"><code>&lt;div&gt;{{selections | json}}&lt;/div&gt;
  &lt;mat-selection-list [(ngModel)]="selections"&gt;
    &lt;sub&gt;&lt;/sub&gt;
  &lt;/mat-selection-list&gt;
  </code></pre>
  
  <p>(sub.component.html)</p>
  
  <pre class="lang-html prettyprint-override"><code>  &lt;mat-list-option [value]="{x: 1}"&gt;x: 1&lt;/mat-list-option&gt;
    &lt;mat-list-option [value]="{x: 2}"&gt;x: 2&lt;/mat-list-option&gt;
    &lt;mat-list-option [value]="{y: 1}"&gt;y: 1&lt;/mat-list-option&gt;
    &lt;mat-list-option [value]="{y: 2}"&gt;y: 2&lt;/mat-list-option&gt;
  </code></pre>
  
  <p>(app.component.ts unchanged; sub.component.ts trivial)</p>
  
  <p>This example does render all options as expected. Their selections are not reflected back to the <code>selections</code> property (as expected too, because at the point each <code>&lt;mat-list-option&gt;</code> get instantiated there is no visible <code>&lt;mat-selection-list&gt;</code> for them to subscribe to).</p>
  
  <p><strong>Example 3</strong> (trying to forward <code>&lt;mat-selection-list&gt;</code>, to no avail)</p>
  
  <p>(app.component.ts)</p>
  
  <pre class="lang-js prettyprint-override"><code>@Component({
    ...
    viewProviders: [{ provide: MatSelectionList, useExisting: MatSelectionList }]
  })
  export class AppComponent {
    selections = [];
  }
  </code></pre>
  
  <p>I expected that this one would work. But I could only get an error:</p>
  
  <pre><code>Cannot instantiate cyclic dependency! MatSelectionList (...)
  </code></pre>
  
  <p>How to make this work?</p>
  
  <p><strong>Note</strong></p>
  
  <p>I'd like to observe that  <code>ngModel</code> directive (which works in tandem with <code>ngForm</code> and/or <code>ngModelGroup</code>) works perfectly across template boundaries just by adding the appropriate <code>viewProviders</code> to all intervening components between the one instantiating <code>ngForm</code> or <code>ngModelGroup</code> (inclusive) and the one instantiating <code>ngModel</code> (exclusive).</p>
  
  <p>Their injection pathways are not the same though: <code>ngModel</code> gets hold of its parent <code>ControlContainer</code> (which subsumes <code>ngForm</code> and <code>ngModelGroup</code>) via <sup>[<a href="https://github.com/angular/angular/blob/ecffbda664e89c565f5521f33d65ae40618a3f09/packages/forms/src/directives/ng_model.ts#L195" rel="nofollow noreferrer">source</a>]</sup>:</p>
  
  <pre class="lang-js prettyprint-override"><code>constructor(@Optional() @Host() parent: ControlContainer, ...) {...}
  </code></pre>
  
  <p>while <code>&lt;mat-list-option&gt;</code> does so by <sup>[<a href="https://github.com/angular/components/blob/3ec531b71a931a53be0c63c41245e4fc48c4554e/src/material/list/selection-list.ts#L176" rel="nofollow noreferrer">source</a>]</sup>:</p>
  
  <pre class="lang-js prettyprint-override"><code>constructor(..., @Inject(forwardRef(() =&gt; MatSelectionList)) public selectionList: MatSelectionList) {...}
  </code></pre>
  
  <p>I'm not angular-savvy to know the differences and their implications.</p>