Reputation: 1031
(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!
Upvotes: 52
Views: 37787
Reputation: 1793
@Input() appFallback: string;
@HostBinding('attr.src') @Input() src: string;
@HostListener('error') loadFallback(): void {
if (this.src === this.appFallback) {
return;
}
this.src = this.appFallback;
}
Upvotes: 3
Reputation: 1450
declare hostbinding property with input property.
@HostBinding('attr.aaa') @Input() aaa: boolean = false;
set hostbinding property to input property
@Input() aaa: string;
@HostBinding('attr.bbb') ccc: string;
ngOnInit(){
this.ccc = this.aaa;
}
Upvotes: 6
Reputation: 313
If your @Input
is an object, you can do:
@Input() settings: Settings;
@HostBinding('class.active')
public get isActive(): boolean {
return this.settings.isActive;
}
Upvotes: 20
Reputation: 10396
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;
}
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:
@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: {} };
}
}
Upvotes: 0
Reputation: 1269
You need to combine the decorators like this:
@HostBinding('class.active') @Input() active: boolean = false;
Upvotes: 118
Reputation: 657268
@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.
Upvotes: 9