{"id":2125,"date":"2017-05-26T12:55:30","date_gmt":"2017-05-26T12:55:30","guid":{"rendered":"http:\/\/salientsoft.co.uk\/?p=2125"},"modified":"2018-10-10T17:15:56","modified_gmt":"2018-10-10T17:15:56","slug":"dynamically-updating-css-classes-on-child-components-from-a-parent-property","status":"publish","type":"post","link":"https:\/\/salientsoft.co.uk\/?p=2125","title":{"rendered":"Dynamically updating css classes on child components from a parent property"},"content":{"rendered":"<p>I was using a button component to encapsulate the primeNG one, to allow it to responsively change to an icon only button at smaller screen widths. Whilst in theory I could have dynamically modified the internal primeNG button CSS, this was complex and I did not want&#160; to become tightly coupled to it. My button component therefore simply selected one of 2 buttons via a media query, setting the unwanted one to <em>display:none<\/em>.<\/p>\n<p>I wanted any classes added to the top level ss-button to be set on the underlying primeNG buttons. One use of these buttons was in a home brewed tab component, and&#160; I was dynamically changing the button colour via ui-button-primary, ui-button-secondary so that the active tab had a \u2018primary\u2019 coloured button and the inactive ones were \u2018secondary\u2019 which caused them to become uncoloured ghost buttons \u2013 ideal for my requirement.<\/p>\n<p>During refactoring to replace the \u2018full size only\u2019 primeNG buttons with the resizing ss-buttons I introduced a bug and the colour change failed to work. The initial (incorrect) refactored code was as follows:-<\/p>\n<h4>ss-tab-toolbar.component.html<\/h4>\n<blockquote>\n<pre>&lt;ng-container *ngFor=&quot;let tab of tabs&quot;&gt;<br \/>  &lt;app-ss-button [label]=&quot;tab.label&quot; [icon]=&quot;tab.icon&quot; (click)=&quot;setActiveTab(tab)&quot;<br \/>          [ngClass]=&quot;{'ui-button-primary': isActiveTab(tab), 'ui-button-secondary': ! isActiveTab(tab)}&quot;&gt;&lt;\/app-ss-button&gt;<br \/>&lt;\/ng-container&gt;<\/pre>\n<\/blockquote>\n<h4>ss-button.component.html<\/h4>\n<blockquote>\n<pre>&lt;button pButton type=&quot;button&quot; [title]=&quot;label&quot; [label]=&quot;label&quot; [icon]=&quot;icon&quot; class=&quot;ss-button icon-text&quot;<br \/>        [ngClass]=&quot;class&quot; &gt;&lt;\/button&gt;<br \/>&lt;button pButton type=&quot;button&quot; [title]=&quot;label&quot; [icon]=&quot;icon&quot; class=&quot;ss-button icon-only&quot;<br \/>        [ngClass]=&quot;class&quot; &gt;&lt;\/button&gt;<\/pre>\n<\/blockquote>\n<h4>ss-button.component.ts<\/h4>\n<blockquote>\n<pre>@Component({<br \/>  selector: 'app-ss-button',<br \/>  templateUrl: '.\/ss-button.component.html',<br \/>  styleUrls: ['.\/ss-button.component.scss']<br \/>})<br \/>export class SSTabButtonComponent  {<br \/><br \/>  @Input() label: string;<br \/>  @Input() icon: string;<br \/>  @Input() class: string;<br \/><br \/>  constructor() { }<br \/>}<\/pre>\n<\/blockquote>\n<p>The issue was that I was using [ngClass] dynamically to update the classes on the <em>&lt;app-ss-button&gt; <\/em>in <em>ss-tab-toolbar.component. html.<\/em> This used to work for the PrimeNG buttons, but now would have no effect as the classes need to be changed on the child buttons not the encapsulating parent. A simple change of [ngClass] to [class] fixed the problem, as the parent style change then updated the property on the parent component which was then picked up by the children correctly.<\/p>\n<p>modified ss-tab-toolbar.component.html<\/p>\n<blockquote>\n<pre>&lt;ng-container *ngFor=&quot;let tab of tabs&quot;&gt;<br \/>  &lt;app-ss-button [label]=&quot;tab.label&quot; [icon]=&quot;tab.icon&quot; (click)=&quot;setActiveTab(tab)&quot;<br \/>          [class]=&quot;{'ui-button-primary': isActiveTab(tab), 'ui-button-secondary': ! isActiveTab(tab)}&quot;&gt;&lt;\/app-ss-button&gt;<br \/>&lt;\/ng-container&gt;<\/pre>\n<\/blockquote>\n<p>Happily the dynamic nature of angular meant that this worked perfectly for tab changes \u2013 the change on the parent class was propagated correctly to the child and the button colours changed correctly.<\/p>\n<p>I was wondering initially whether I would need to involve observables to make this work but this was not the case \u2013 this kind of dynamic propagation pattern is worth remembering in future.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was using a button component to encapsulate the primeNG one, to allow it to responsively change to an icon only button at smaller screen widths. Whilst in theory I could have dynamically modified the internal primeNG button CSS, this was complex and I did not want&#160; to become tightly coupled to it. My button [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[198,79,209],"tags":[199,40,16,15],"_links":{"self":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/2125"}],"collection":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2125"}],"version-history":[{"count":2,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/2125\/revisions"}],"predecessor-version":[{"id":2128,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/2125\/revisions\/2128"}],"wp:attachment":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2125"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2125"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2125"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}