Can I do two things at once in a structural directive?
I'd like to create a structural directive which behaves as follows:
<p *myDirective="condition">This is some text</p>
- If
condition
isfalse
then the<p>
tag is not rendered at all. - If
condition
istrue
then the<p>
tag is rendered with an extraclass
attribute.
So, either there's nothing rendered, or:
<p class="my-added-class">This is some text</p>
In other words, it's a bit like *ngIf
, but with additional behaviour.
I can find examples of how to do the include/exclude behaviour (in fact there is such an example in the Angular docs). I can also find examples of how to add a class to an element using the Renderer2
API.
However, I don't see how I can combine these techniques, because the first method manipulates the viewContainer
to create an embedded view, whereas the second method uses the renderer to manipulate an element.
Is there a way to do this? Can I somehow create the embedded view and then manipulate the elements it creates? Or can I manipulate the template to change how the view is rendered?
[NOTE: @HostBinding
does not work with structural directives, so that's not an option]
angular angular-directive
add a comment |
I'd like to create a structural directive which behaves as follows:
<p *myDirective="condition">This is some text</p>
- If
condition
isfalse
then the<p>
tag is not rendered at all. - If
condition
istrue
then the<p>
tag is rendered with an extraclass
attribute.
So, either there's nothing rendered, or:
<p class="my-added-class">This is some text</p>
In other words, it's a bit like *ngIf
, but with additional behaviour.
I can find examples of how to do the include/exclude behaviour (in fact there is such an example in the Angular docs). I can also find examples of how to add a class to an element using the Renderer2
API.
However, I don't see how I can combine these techniques, because the first method manipulates the viewContainer
to create an embedded view, whereas the second method uses the renderer to manipulate an element.
Is there a way to do this? Can I somehow create the embedded view and then manipulate the elements it creates? Or can I manipulate the template to change how the view is rendered?
[NOTE: @HostBinding
does not work with structural directives, so that's not an option]
angular angular-directive
1
Why don't you want to just use*ngIf
along withngClass
and do the needful based on a condition? Something like<p *ngIf="condition" [class.yourClass]="condition">This is some text</p>
– SiddAjmera
Nov 15 '18 at 18:14
When you create the embedded view, you can grab the rendered elements with the rootNodes property:const viewRef = this.viewContainer.createEmbeddedView(this.templateRef); viewRef.rootNodes[0].classList.add('my-added-class');
Demo: stackblitz.com/edit/angular-1mdlht
– Alex K
Nov 15 '18 at 18:15
@SiddAjmera: Errrm… because I want to wrap those two things together in a directive? So that every time I use it, I just need to type a single directive, and it does everything for me. I mean, I could just type everything out, but… I could just use HTML :-)
– Gary McGill
Nov 15 '18 at 22:15
@AlexK: that looks perfect - thanks!
– Gary McGill
Nov 15 '18 at 22:19
add a comment |
I'd like to create a structural directive which behaves as follows:
<p *myDirective="condition">This is some text</p>
- If
condition
isfalse
then the<p>
tag is not rendered at all. - If
condition
istrue
then the<p>
tag is rendered with an extraclass
attribute.
So, either there's nothing rendered, or:
<p class="my-added-class">This is some text</p>
In other words, it's a bit like *ngIf
, but with additional behaviour.
I can find examples of how to do the include/exclude behaviour (in fact there is such an example in the Angular docs). I can also find examples of how to add a class to an element using the Renderer2
API.
However, I don't see how I can combine these techniques, because the first method manipulates the viewContainer
to create an embedded view, whereas the second method uses the renderer to manipulate an element.
Is there a way to do this? Can I somehow create the embedded view and then manipulate the elements it creates? Or can I manipulate the template to change how the view is rendered?
[NOTE: @HostBinding
does not work with structural directives, so that's not an option]
angular angular-directive
I'd like to create a structural directive which behaves as follows:
<p *myDirective="condition">This is some text</p>
- If
condition
isfalse
then the<p>
tag is not rendered at all. - If
condition
istrue
then the<p>
tag is rendered with an extraclass
attribute.
So, either there's nothing rendered, or:
<p class="my-added-class">This is some text</p>
In other words, it's a bit like *ngIf
, but with additional behaviour.
I can find examples of how to do the include/exclude behaviour (in fact there is such an example in the Angular docs). I can also find examples of how to add a class to an element using the Renderer2
API.
However, I don't see how I can combine these techniques, because the first method manipulates the viewContainer
to create an embedded view, whereas the second method uses the renderer to manipulate an element.
Is there a way to do this? Can I somehow create the embedded view and then manipulate the elements it creates? Or can I manipulate the template to change how the view is rendered?
[NOTE: @HostBinding
does not work with structural directives, so that's not an option]
angular angular-directive
angular angular-directive
asked Nov 15 '18 at 18:00
Gary McGillGary McGill
16.6k1991162
16.6k1991162
1
Why don't you want to just use*ngIf
along withngClass
and do the needful based on a condition? Something like<p *ngIf="condition" [class.yourClass]="condition">This is some text</p>
– SiddAjmera
Nov 15 '18 at 18:14
When you create the embedded view, you can grab the rendered elements with the rootNodes property:const viewRef = this.viewContainer.createEmbeddedView(this.templateRef); viewRef.rootNodes[0].classList.add('my-added-class');
Demo: stackblitz.com/edit/angular-1mdlht
– Alex K
Nov 15 '18 at 18:15
@SiddAjmera: Errrm… because I want to wrap those two things together in a directive? So that every time I use it, I just need to type a single directive, and it does everything for me. I mean, I could just type everything out, but… I could just use HTML :-)
– Gary McGill
Nov 15 '18 at 22:15
@AlexK: that looks perfect - thanks!
– Gary McGill
Nov 15 '18 at 22:19
add a comment |
1
Why don't you want to just use*ngIf
along withngClass
and do the needful based on a condition? Something like<p *ngIf="condition" [class.yourClass]="condition">This is some text</p>
– SiddAjmera
Nov 15 '18 at 18:14
When you create the embedded view, you can grab the rendered elements with the rootNodes property:const viewRef = this.viewContainer.createEmbeddedView(this.templateRef); viewRef.rootNodes[0].classList.add('my-added-class');
Demo: stackblitz.com/edit/angular-1mdlht
– Alex K
Nov 15 '18 at 18:15
@SiddAjmera: Errrm… because I want to wrap those two things together in a directive? So that every time I use it, I just need to type a single directive, and it does everything for me. I mean, I could just type everything out, but… I could just use HTML :-)
– Gary McGill
Nov 15 '18 at 22:15
@AlexK: that looks perfect - thanks!
– Gary McGill
Nov 15 '18 at 22:19
1
1
Why don't you want to just use
*ngIf
along with ngClass
and do the needful based on a condition? Something like <p *ngIf="condition" [class.yourClass]="condition">This is some text</p>
– SiddAjmera
Nov 15 '18 at 18:14
Why don't you want to just use
*ngIf
along with ngClass
and do the needful based on a condition? Something like <p *ngIf="condition" [class.yourClass]="condition">This is some text</p>
– SiddAjmera
Nov 15 '18 at 18:14
When you create the embedded view, you can grab the rendered elements with the rootNodes property:
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef); viewRef.rootNodes[0].classList.add('my-added-class');
Demo: stackblitz.com/edit/angular-1mdlht– Alex K
Nov 15 '18 at 18:15
When you create the embedded view, you can grab the rendered elements with the rootNodes property:
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef); viewRef.rootNodes[0].classList.add('my-added-class');
Demo: stackblitz.com/edit/angular-1mdlht– Alex K
Nov 15 '18 at 18:15
@SiddAjmera: Errrm… because I want to wrap those two things together in a directive? So that every time I use it, I just need to type a single directive, and it does everything for me. I mean, I could just type everything out, but… I could just use HTML :-)
– Gary McGill
Nov 15 '18 at 22:15
@SiddAjmera: Errrm… because I want to wrap those two things together in a directive? So that every time I use it, I just need to type a single directive, and it does everything for me. I mean, I could just type everything out, but… I could just use HTML :-)
– Gary McGill
Nov 15 '18 at 22:15
@AlexK: that looks perfect - thanks!
– Gary McGill
Nov 15 '18 at 22:19
@AlexK: that looks perfect - thanks!
– Gary McGill
Nov 15 '18 at 22:19
add a comment |
2 Answers
2
active
oldest
votes
An other way
just to play around :)
Using Renderer2 is universal safe
import
Directive,
Renderer2,
TemplateRef,
ViewContainerRef,
ElementRef,
Input, OnInit from '@angular/core';
@Directive(
selector: '[appMy]'
)
export class MyDirective implements OnInit
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private renderer: Renderer2)
@Input() set appMy(condition: boolean)
if (condition)
this.viewContainer.createEmbeddedView(this.templateRef);
else
this.viewContainer.clear();
ngOnInit()
const elementRef = this.viewContainer.get(0).rootNodes[0] as ElementRef;
this.renderer.addClass(elementRef, 'myclass');
Following the @Pankaj way but with renderer
@Input() set appMy(condition: boolean)
if (condition)
const view = this.viewContainer.createEmbeddedView(this.templateRef);
this.renderer.addClass(view.rootNodes[0], 'myclass');
else
this.viewContainer.clear();
1
Thanks. I went with your second suggestion, because it puts everything in one place, and because it doesn't involve injecting the ElementRef etc. One thing to note is that it works for<p *myDirective="condition">text</p>
but not for<ng-template myCondition="condition">text</ng-template>
because in the latter case there's no element to add a class to. (I can live with that).
– Gary McGill
Nov 16 '18 at 9:16
add a comment |
I'd think of adding class on the DOM when it satisfied the expression passed to it (inside setter). You can grab the ElementRef
dependency inside directive and append a class
to it which its truthy.
@Input() set myDirective(condition: boolean)
if (condition)
this.viewContainer.createEmbeddedView(this.templateRef);
this.elementRef.nativeElement.nextElementSibling.classList.add('my-added-class'); // renderer API can be used here
// as Alex and Yurzui suggested
// const view = this.viewContainer.createEmbeddedView(this.templateRef);
// view.rootNodes[0].classList.add('some-class')
else if (condition)
this.viewContainer.clear();
Tried that. But it gives an error sayingERROR TypeError: Cannot read property 'add' of undefined
– SiddAjmera
Nov 15 '18 at 18:22
Don't forget that for structural directive elementRef refers to the comment node
– yurzui
Nov 15 '18 at 18:23
@yurzui my bad. thanks mate for pointing it out.
– Pankaj Parkar
Nov 15 '18 at 18:24
Another way isconst view = this.viewContainer.createEmbeddedView(this.templateRef); view.rootNodes[0].classList.add('some-class')
but we should know exactly that template contains element on top level
– yurzui
Nov 15 '18 at 18:25
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53325398%2fcan-i-do-two-things-at-once-in-a-structural-directive%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
An other way
just to play around :)
Using Renderer2 is universal safe
import
Directive,
Renderer2,
TemplateRef,
ViewContainerRef,
ElementRef,
Input, OnInit from '@angular/core';
@Directive(
selector: '[appMy]'
)
export class MyDirective implements OnInit
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private renderer: Renderer2)
@Input() set appMy(condition: boolean)
if (condition)
this.viewContainer.createEmbeddedView(this.templateRef);
else
this.viewContainer.clear();
ngOnInit()
const elementRef = this.viewContainer.get(0).rootNodes[0] as ElementRef;
this.renderer.addClass(elementRef, 'myclass');
Following the @Pankaj way but with renderer
@Input() set appMy(condition: boolean)
if (condition)
const view = this.viewContainer.createEmbeddedView(this.templateRef);
this.renderer.addClass(view.rootNodes[0], 'myclass');
else
this.viewContainer.clear();
1
Thanks. I went with your second suggestion, because it puts everything in one place, and because it doesn't involve injecting the ElementRef etc. One thing to note is that it works for<p *myDirective="condition">text</p>
but not for<ng-template myCondition="condition">text</ng-template>
because in the latter case there's no element to add a class to. (I can live with that).
– Gary McGill
Nov 16 '18 at 9:16
add a comment |
An other way
just to play around :)
Using Renderer2 is universal safe
import
Directive,
Renderer2,
TemplateRef,
ViewContainerRef,
ElementRef,
Input, OnInit from '@angular/core';
@Directive(
selector: '[appMy]'
)
export class MyDirective implements OnInit
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private renderer: Renderer2)
@Input() set appMy(condition: boolean)
if (condition)
this.viewContainer.createEmbeddedView(this.templateRef);
else
this.viewContainer.clear();
ngOnInit()
const elementRef = this.viewContainer.get(0).rootNodes[0] as ElementRef;
this.renderer.addClass(elementRef, 'myclass');
Following the @Pankaj way but with renderer
@Input() set appMy(condition: boolean)
if (condition)
const view = this.viewContainer.createEmbeddedView(this.templateRef);
this.renderer.addClass(view.rootNodes[0], 'myclass');
else
this.viewContainer.clear();
1
Thanks. I went with your second suggestion, because it puts everything in one place, and because it doesn't involve injecting the ElementRef etc. One thing to note is that it works for<p *myDirective="condition">text</p>
but not for<ng-template myCondition="condition">text</ng-template>
because in the latter case there's no element to add a class to. (I can live with that).
– Gary McGill
Nov 16 '18 at 9:16
add a comment |
An other way
just to play around :)
Using Renderer2 is universal safe
import
Directive,
Renderer2,
TemplateRef,
ViewContainerRef,
ElementRef,
Input, OnInit from '@angular/core';
@Directive(
selector: '[appMy]'
)
export class MyDirective implements OnInit
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private renderer: Renderer2)
@Input() set appMy(condition: boolean)
if (condition)
this.viewContainer.createEmbeddedView(this.templateRef);
else
this.viewContainer.clear();
ngOnInit()
const elementRef = this.viewContainer.get(0).rootNodes[0] as ElementRef;
this.renderer.addClass(elementRef, 'myclass');
Following the @Pankaj way but with renderer
@Input() set appMy(condition: boolean)
if (condition)
const view = this.viewContainer.createEmbeddedView(this.templateRef);
this.renderer.addClass(view.rootNodes[0], 'myclass');
else
this.viewContainer.clear();
An other way
just to play around :)
Using Renderer2 is universal safe
import
Directive,
Renderer2,
TemplateRef,
ViewContainerRef,
ElementRef,
Input, OnInit from '@angular/core';
@Directive(
selector: '[appMy]'
)
export class MyDirective implements OnInit
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private renderer: Renderer2)
@Input() set appMy(condition: boolean)
if (condition)
this.viewContainer.createEmbeddedView(this.templateRef);
else
this.viewContainer.clear();
ngOnInit()
const elementRef = this.viewContainer.get(0).rootNodes[0] as ElementRef;
this.renderer.addClass(elementRef, 'myclass');
Following the @Pankaj way but with renderer
@Input() set appMy(condition: boolean)
if (condition)
const view = this.viewContainer.createEmbeddedView(this.templateRef);
this.renderer.addClass(view.rootNodes[0], 'myclass');
else
this.viewContainer.clear();
edited Nov 15 '18 at 20:19
answered Nov 15 '18 at 19:57
WhisherWhisher
11.1k2282149
11.1k2282149
1
Thanks. I went with your second suggestion, because it puts everything in one place, and because it doesn't involve injecting the ElementRef etc. One thing to note is that it works for<p *myDirective="condition">text</p>
but not for<ng-template myCondition="condition">text</ng-template>
because in the latter case there's no element to add a class to. (I can live with that).
– Gary McGill
Nov 16 '18 at 9:16
add a comment |
1
Thanks. I went with your second suggestion, because it puts everything in one place, and because it doesn't involve injecting the ElementRef etc. One thing to note is that it works for<p *myDirective="condition">text</p>
but not for<ng-template myCondition="condition">text</ng-template>
because in the latter case there's no element to add a class to. (I can live with that).
– Gary McGill
Nov 16 '18 at 9:16
1
1
Thanks. I went with your second suggestion, because it puts everything in one place, and because it doesn't involve injecting the ElementRef etc. One thing to note is that it works for
<p *myDirective="condition">text</p>
but not for <ng-template myCondition="condition">text</ng-template>
because in the latter case there's no element to add a class to. (I can live with that).– Gary McGill
Nov 16 '18 at 9:16
Thanks. I went with your second suggestion, because it puts everything in one place, and because it doesn't involve injecting the ElementRef etc. One thing to note is that it works for
<p *myDirective="condition">text</p>
but not for <ng-template myCondition="condition">text</ng-template>
because in the latter case there's no element to add a class to. (I can live with that).– Gary McGill
Nov 16 '18 at 9:16
add a comment |
I'd think of adding class on the DOM when it satisfied the expression passed to it (inside setter). You can grab the ElementRef
dependency inside directive and append a class
to it which its truthy.
@Input() set myDirective(condition: boolean)
if (condition)
this.viewContainer.createEmbeddedView(this.templateRef);
this.elementRef.nativeElement.nextElementSibling.classList.add('my-added-class'); // renderer API can be used here
// as Alex and Yurzui suggested
// const view = this.viewContainer.createEmbeddedView(this.templateRef);
// view.rootNodes[0].classList.add('some-class')
else if (condition)
this.viewContainer.clear();
Tried that. But it gives an error sayingERROR TypeError: Cannot read property 'add' of undefined
– SiddAjmera
Nov 15 '18 at 18:22
Don't forget that for structural directive elementRef refers to the comment node
– yurzui
Nov 15 '18 at 18:23
@yurzui my bad. thanks mate for pointing it out.
– Pankaj Parkar
Nov 15 '18 at 18:24
Another way isconst view = this.viewContainer.createEmbeddedView(this.templateRef); view.rootNodes[0].classList.add('some-class')
but we should know exactly that template contains element on top level
– yurzui
Nov 15 '18 at 18:25
add a comment |
I'd think of adding class on the DOM when it satisfied the expression passed to it (inside setter). You can grab the ElementRef
dependency inside directive and append a class
to it which its truthy.
@Input() set myDirective(condition: boolean)
if (condition)
this.viewContainer.createEmbeddedView(this.templateRef);
this.elementRef.nativeElement.nextElementSibling.classList.add('my-added-class'); // renderer API can be used here
// as Alex and Yurzui suggested
// const view = this.viewContainer.createEmbeddedView(this.templateRef);
// view.rootNodes[0].classList.add('some-class')
else if (condition)
this.viewContainer.clear();
Tried that. But it gives an error sayingERROR TypeError: Cannot read property 'add' of undefined
– SiddAjmera
Nov 15 '18 at 18:22
Don't forget that for structural directive elementRef refers to the comment node
– yurzui
Nov 15 '18 at 18:23
@yurzui my bad. thanks mate for pointing it out.
– Pankaj Parkar
Nov 15 '18 at 18:24
Another way isconst view = this.viewContainer.createEmbeddedView(this.templateRef); view.rootNodes[0].classList.add('some-class')
but we should know exactly that template contains element on top level
– yurzui
Nov 15 '18 at 18:25
add a comment |
I'd think of adding class on the DOM when it satisfied the expression passed to it (inside setter). You can grab the ElementRef
dependency inside directive and append a class
to it which its truthy.
@Input() set myDirective(condition: boolean)
if (condition)
this.viewContainer.createEmbeddedView(this.templateRef);
this.elementRef.nativeElement.nextElementSibling.classList.add('my-added-class'); // renderer API can be used here
// as Alex and Yurzui suggested
// const view = this.viewContainer.createEmbeddedView(this.templateRef);
// view.rootNodes[0].classList.add('some-class')
else if (condition)
this.viewContainer.clear();
I'd think of adding class on the DOM when it satisfied the expression passed to it (inside setter). You can grab the ElementRef
dependency inside directive and append a class
to it which its truthy.
@Input() set myDirective(condition: boolean)
if (condition)
this.viewContainer.createEmbeddedView(this.templateRef);
this.elementRef.nativeElement.nextElementSibling.classList.add('my-added-class'); // renderer API can be used here
// as Alex and Yurzui suggested
// const view = this.viewContainer.createEmbeddedView(this.templateRef);
// view.rootNodes[0].classList.add('some-class')
else if (condition)
this.viewContainer.clear();
edited Nov 15 '18 at 18:43
answered Nov 15 '18 at 18:15
Pankaj ParkarPankaj Parkar
114k16165238
114k16165238
Tried that. But it gives an error sayingERROR TypeError: Cannot read property 'add' of undefined
– SiddAjmera
Nov 15 '18 at 18:22
Don't forget that for structural directive elementRef refers to the comment node
– yurzui
Nov 15 '18 at 18:23
@yurzui my bad. thanks mate for pointing it out.
– Pankaj Parkar
Nov 15 '18 at 18:24
Another way isconst view = this.viewContainer.createEmbeddedView(this.templateRef); view.rootNodes[0].classList.add('some-class')
but we should know exactly that template contains element on top level
– yurzui
Nov 15 '18 at 18:25
add a comment |
Tried that. But it gives an error sayingERROR TypeError: Cannot read property 'add' of undefined
– SiddAjmera
Nov 15 '18 at 18:22
Don't forget that for structural directive elementRef refers to the comment node
– yurzui
Nov 15 '18 at 18:23
@yurzui my bad. thanks mate for pointing it out.
– Pankaj Parkar
Nov 15 '18 at 18:24
Another way isconst view = this.viewContainer.createEmbeddedView(this.templateRef); view.rootNodes[0].classList.add('some-class')
but we should know exactly that template contains element on top level
– yurzui
Nov 15 '18 at 18:25
Tried that. But it gives an error saying
ERROR TypeError: Cannot read property 'add' of undefined
– SiddAjmera
Nov 15 '18 at 18:22
Tried that. But it gives an error saying
ERROR TypeError: Cannot read property 'add' of undefined
– SiddAjmera
Nov 15 '18 at 18:22
Don't forget that for structural directive elementRef refers to the comment node
– yurzui
Nov 15 '18 at 18:23
Don't forget that for structural directive elementRef refers to the comment node
– yurzui
Nov 15 '18 at 18:23
@yurzui my bad. thanks mate for pointing it out.
– Pankaj Parkar
Nov 15 '18 at 18:24
@yurzui my bad. thanks mate for pointing it out.
– Pankaj Parkar
Nov 15 '18 at 18:24
Another way is
const view = this.viewContainer.createEmbeddedView(this.templateRef); view.rootNodes[0].classList.add('some-class')
but we should know exactly that template contains element on top level– yurzui
Nov 15 '18 at 18:25
Another way is
const view = this.viewContainer.createEmbeddedView(this.templateRef); view.rootNodes[0].classList.add('some-class')
but we should know exactly that template contains element on top level– yurzui
Nov 15 '18 at 18:25
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53325398%2fcan-i-do-two-things-at-once-in-a-structural-directive%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Why don't you want to just use
*ngIf
along withngClass
and do the needful based on a condition? Something like<p *ngIf="condition" [class.yourClass]="condition">This is some text</p>
– SiddAjmera
Nov 15 '18 at 18:14
When you create the embedded view, you can grab the rendered elements with the rootNodes property:
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef); viewRef.rootNodes[0].classList.add('my-added-class');
Demo: stackblitz.com/edit/angular-1mdlht– Alex K
Nov 15 '18 at 18:15
@SiddAjmera: Errrm… because I want to wrap those two things together in a directive? So that every time I use it, I just need to type a single directive, and it does everything for me. I mean, I could just type everything out, but… I could just use HTML :-)
– Gary McGill
Nov 15 '18 at 22:15
@AlexK: that looks perfect - thanks!
– Gary McGill
Nov 15 '18 at 22:19