52

(Angular 2 RC4)

With @HostBinding we should be able to modify properties of the host, right? My question is, does this apply to @Input() properties as well and if so, what is the correct usage? If not, is there another way to achieve this?

I made a Plunker here to illustrate my problem: https://embed.plnkr.co/kQEKbT/

Suppose I have a custom component:

@Component({
  selector: 'custom-img',
  template: `
    <img src="{{src}}">
  `
})
export class CustomImgComponent {
  @Input() src: string;
}

And I want to feed the src property with an attribute directive:

@Directive({
  selector: '[srcKey]'
})
export class SrcKeyDirective implements OnChanges {
  
  @Input() srcKey: string;
  @HostBinding() src;
  
  ngOnChanges() {
    this.src = `https://www.google.com.mt/images/branding/googlelogo/2x/${this.srcKey}_color_272x92dp.png`;
  }
}

Why can't this directive change the [src] input property of the custom component?

@Component({
  selector: 'my-app',
  directives: [CustomImgComponent, SrcKeyDirective],
  template: `<custom-img [srcKey]="imageKey"></custom-img>`
})
export class AppComponent {
  imageKey = "googlelogo";
}

Thanks!

6 Answers 6

119

You need to combine the decorators like this:

@HostBinding('class.active') @Input() active: boolean = false;

Sign up to request clarification or add additional context in comments.

4 Comments

What would I do if my input is an object and I want to bind a property of this object?
@hugoderhungrige Did you happen to resolve this issue? How to do host binding on a property of an object...
@RobertKoritnik check my answer, it allows you to use property of an object
Classic Stack Overflow: scroll to the bottom to find the right answer.
20

If your @Input is an object, you can do:

@Input() settings: Settings;

@HostBinding('class.active')
public get isActive(): boolean {
  return this.settings.isActive;
}

1 Comment

Gave me trouble. See my answer above
9

@HostBinding() doesn't create property bindings to properties of the host component. That might be worth a bug report though ;-)

I got it working by a workaround with exportAs and a template variable but that is quite ugly. https://plnkr.co/edit/TobNVn?p=preview

After some consideration, I think it should work. Otherwise I wouldn't know what @HostBinding() src; would do at all.

@HostBinding('attr.src') src; or @HostBinding('class.src') src; are the more common cases.

3 Comments

Thank you for the quick response. I made a bug report here: github.com/angular/angular/issues/10499
This answer has too much text noise, it's a bit unclear what's the solution.
not applicable in 2021, check Piizei 's answer
6
  1. declare hostbinding property with input property.

    @HostBinding('attr.aaa') @Input() aaa: boolean = false;
    
  2. set hostbinding property to input property

    @Input() aaa: string;
    @HostBinding('attr.bbb') ccc: string;
    
    ngOnInit(){
      this.ccc = this.aaa;
    }
    

1 Comment

as of Angular 8.2, Hostbinding (in my case: for Angular animation) does work like this: @HostBinding('@childAnim') @Input() shrink = false;
3
@Input() appFallback: string;

@HostBinding('attr.src') @Input() src: string;

@HostListener('error') loadFallback(): void {

  if (this.src === this.appFallback) {
    return;
  }
  this.src = this.appFallback;
}

Comments

0

BEWARE on using get with hostbinding.

At least I an endless recursion (thousands of cycles). Put a console.log in the get function to check:

@HostBinding('@someAnim') get whatever() {
    console.log('#### traffic.....');
    return true;
}

I even got that trouble, when just changing some class (so nothing around fancy Angular animation) and not even relying on any other class member whatsoever:

@HostBinding('class.foobar') get _____() {
    console.log('#### more traffic.....');
    return true;
}

enter image description here

An addition, it doesn't hurt to have this in your component while developing (as a “free flow canary”):

ngOnChanges(changes: SimpleChanges) {
    console.log('#### more traffic.....');
}

You should only see one log entry per, say, state-change and instantiated component, anyway not thousands...

—At last— I had luck with this one:

  • distinct variable for incoming (@Input) and outgoing (@HostBinding)
  • changing the outgoing upon change
  • → no „free flow“
    @Input() animTileAttrib = false;
    @HostBinding('@animTile') paramPack: AnimParams = { value: false, params: {}};

    ngOnChanges(changes: SimpleChanges) {
        console.log('#### traffic.....');
        if ('animTileAttrib' in changes) {
            this.paramPack = { value: changes.animTileAttrib.currentValue, params: {} };
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.