angular: @Directive @Hostbinding cannot set @Input of @Component
I’m submitting a bug
[X] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
This is an issue similar to #10499. There seems to be a problem whereby an @Directive
cannot set an @Component
input property. Meaning if you apply a directive to the component’s tag and have said directive set the component’s input property using an @Hostbinding
it throws the following error:
Can't bind to 'X' since it isn't a known property of 'X'.
Expected behavior I hoped it would be possible to set an Component’s input property using a simple Directive. Though I would also understand that if this is by design. If it’s by design then i think the error message reported back to the user should be improved as it doesn’t clearly indicate why it isn’t work as the programmer might expect it to work.
Minimal reproduction of the problem with instructions https://plnkr.co/edit/V2KBlhbv7AciGfEi0lkE
What is the motivation / use case for changing the behavior?
There are a few use cases that would be simplified by having the ability for having an @Directive
being able to set the component’s Input property without modifications to the source Component. One of the use cases highlighted in the example above resolves around the md-input from @angular/material2 (using an external library over which you have no influence). Where a [disabled]
property can be set indicating if the component is disabled. We have wanted to use this together with an role checking directive to disable / enable an input based on the user’s role / permissions.
There are of course other ways like wrapping the md-input
and all of the other input’s @angular/material2 provides in our own custom input value access-or components which would do this for us but we thought it would be easier to go down this route instead of wrapping all other inputs.
-
Angular version: 2.0.X 2.4.1
-
Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ] all
-
Language: [all | TypeScript X.X | ES6/7 | ES5] all
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 49
- Comments: 17 (4 by maintainers)
@schippie Instead of wrapping
md-input
inside another component you could inject the component instance from the host element instead.This should work as a temporary solution I guess. Plnkr- https://plnkr.co/edit/yo17tHkWXkMl37LOJvuG?p=preview
Having the exact same issue here. Setting a component input from outside by using a directive with host binding is an elegant pattern, as it makes component-directive interaction easy and allows for more generalization / decoupling of things.
In addition, I wonder why event binding works though, whereas property binding doesn’t.
Any way of seeing some considerations on this? Attribute directives seem like a perfect fit for
redux
-like orngrx/store
-like containers attaching inputs/outputs to existing components without redundant dom-nodes in case of using@Component
instead of@Directive
.I just encountered this issue, were we wanted a directive to set the
checked
input for<input type="checkbox">
and<md-checkbox>
via@HostBinding
. It worked for the former, but not the latter. The error message about not having imported the component module was also really misleading.@ndunks I also need this functionality for
<mat-icon [app-icon]="item.name"></mat-icon>
case. What is proper way of modifing parent (host) component inputs from directive? When I modify host component input and calldetectChanges
ormarkForCheck
from directive thenngOnChanges
does not trigger at the host component.Would the Angular team be able to let us know when/if this will part of one the releases?
Now that we have
setInput
onComponentRef
I think a viable solution is allowing to inject the hostComponentRef
and interact with it like with dynamic components. This will allow the directive to work with the component as if an input was bound. I agree it’s less convenient thanHostBinding
but it’s much better than what we have now (reference component instance and require input get set asngOnChanges
won’t be invoked).+1 for this case:
<mat-icon [app-icon]="item.name"></mat-icon>
AppIcon directive to help choose default icon based on name. I hope this will be fixed.@rusev That’s quite an elegant solution for now indeed, complete forgot about the
@Host
for a moment indeed. But that does highlight the problem even clearer. It is possible for a Directive to tell the Host component about this change. So I’ll keep the bug report open for now.