title: Binding attribute directive to component @ViewChild undefined
body: <p>I created an attribute directive <code>ImageSpinloaderDirective</code> to conditionally change the appearance of the user's profile picture, depending on wether there is a picture and if it is already loaded:</p>
  
  <ul>
  <li>If the <code>src</code> attribute's URL can't be resolved (404, etc), a default
  image should be shown</li>
  <li>If the picture is still loading a loading animation should be shown</li>
  <li>If the user has changed, a new profile image is loaded and the spinloader should appear again until loading is finished</li>
  </ul>
  
  <p>My approach is to listen to the DOM-events <code>load</code> and <code>error</code> in the <code>ImageSpinloaderDirective</code> and to set the <code>src</code> attribute and <code>img-loading</code> class of the <code>&lt;img&gt;</code> element accordingly. The <code>img-loading</code> class sets the images opacitiy to 0 and uses an animated gif as background image.</p>
  
  <p>Now I wanted to change the directive's <code>isLoading</code> field from the parent component (<code>UserDetailsComponent</code>) every time a different user is displayed. I thought that using the <code>@ViewChild</code> annotation within that component would be the right choice to accomplish that. However the binding seems to fail for some reason, since <code>UserDetailsComponent</code>'s <code>imageSpinloaderDirective</code> is always undefined.</p>
  
  <p>Is it possible at all to use attribute directives with the <code>@ViewChild</code> annotation? Is there any better/alternative way to bind an attribute directive to a component? Or is this approach totally wrong and should be implemented in a different way?</p>
  
  <p><strong>user-details.component.ts</strong></p>
  
  <pre><code>Component({
      moduleId: module.id,
      selector: 'user-details',
      templateUrl: 'user-details.html',
      styleUrls: [
          './../grid/grid-item-details.css',
          './../grid/grid.css'
      ],
      animations: [fadeInOut]
  })
  export class UserDetailsComponent extends GridItemDetailsComponent&lt;User&gt;
  {
      public user: User;
      public profileImageUrl: string;
  
      @ViewChild(ImageSpinloaderDirective)
      public imageSpinloaderDirective: ImageSpinloaderDirective;
  
      public loadDetails(item: User): void
      {
          this.user = item;
          this.imageSpinloaderDirective.isLoading = true;
          this.profileImageUrl = `${this.configService.config.profileApiUrl}/image/${item.id}`;
      }
  }
  </code></pre>
  
  <p><strong>user-details.html</strong></p>
  
  <pre><code>&lt;div class="row"&gt;
    &lt;div class="col-lg-12"&gt;
      &lt;div class="img-loader"&gt;
        &lt;img id="foo" imgspinloader
             class="img-rounded"
             src="{{profileImageUrl}}"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p><strong>image-spinloader.directive.ts</strong></p>
  
  <pre><code>import
  {
      AfterContentChecked,
      Directive,
      HostBinding,
      HostListener,
      Input,
      OnInit
  } from '@angular/core';
  
  @Directive({
      selector: '[imgspinloader]'
  })
  export class ImageSpinloaderDirective
  {
      private defaultSrc: string = "assets/img/user-image-invitation-2x.png";
  
      @Input() @HostBinding() src;
  
      @Input() @HostBinding("class.img-loading") isLoading: boolean;
  
      @HostListener('load') complete()
      {
          this.isLoading = false;
      }
  
      @HostListener('error') onError()
      {
          this.src = this.defaultSrc;
          this.isLoading = false;
      }
  }
  </code></pre>