Reputation: 627
I'm using Angular 2 and I would like a directive to modify the behaviour of its host html element. For example, I would like an InnerDirective
with selector '[inner-directive]'
such that:
@Component({
selector: '[outer-component]'
template: `
<div
inner-directive
></div>
`
})
class outerComponent{
someAttribute: boolean;
}
is the same as
@Component({
selector: '[outer-component]'
template: `
<div
[ngClass] = "{'some-class': someAttribute}"
></div>
`
})
class outerComponent{
someAttribute: boolean;
}
I don't want InnerDirective
to be a component with its own template doing the job (with someAttribute
getting passed down) because that would create a redundant html element.
More generally I would like to do whatever can be achieved by putting an empty component inside another component (with the aforementioned html redundancy), by getting the inner component to be a directive instead. That way my "leaves" can all be directives.
Thank you very much for your help.
Upvotes: 1
Views: 4523
Reputation: 657486
@Directive({
selector: '[innerDirective]',
host: {'[class.some-class]': 'innerDirective'}
})
class InnerDirective {
@Input() innerDirective: boolean;
}
host: {'[class.some-class]': 'someAttribute'}
binds the value of the innerDirective
input to some-class
on the host element.
An input with the same name as the selector (@Input() innerDirective: boolean;
) allows terse binding syntax (shown below)
@Component({
selector: '[outer-component]',
directives: [InnerDirective],
template: `
<div [innerDirective]="someAttribute"></div>`
})
class outerComponent{
someAttribute: boolean;
}
[innerDirective]="someAttribute"
binds the someAttribute
value to the innerDirective
input of InnerDirective
.Upvotes: 3
Reputation: 202206
It's typically what attribute directive aims to. It allows to change the appearance or behavior of the element it applies on.
Here is a sample:
@Directive({
selector: '[inner-directive]'
})
export class InnerDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
}
Update
You can leverage the host
attribute when defining your directive
@Directive({
(...)
host: {
'[class.myClass]': 'displayClass',
'[attr.someAttr]': 'someAttrValue',
'[attr.otherAttr]': 'someValue'
}
})
export class InnerDirective {
@Input('innner-directive')
someValue: string;
constructor() {
// myClass is added on the host
this.displayClass = true;
// myClass isn't added on the host
// this.displayClass = false;
this.someAttrValue = 'some value';
}
ngOnInit() {
console.log(this.someValue);
}
}
Upvotes: 1