What is the difference between class and [class] in angular html - html

Looking for good practices about angular folder structure I stumble upon this piece of code:
content-layout.component.html:
<div [class]="theme">
<div class="mat-app-background">
<app-nav></app-nav>
<div class="container">
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
</div>
</div>
As far as I understand, the class tag is used to bind this component HTML with a CSS class.
But the square brackets caught my attention, is there any real difference between the [class] and class for css binding? I can't hit the correct search term/feature name to google it myself

the brackets [] indicate that the value is a property in your component, so instead of saying apply the class theme to the element, it will look for a property theme in your component and use whatever is stored in there.
class="theme" // apply class theme
// Component
public theme = 'theme';
// HTML
[class]="theme" // use what's stored in property "theme"
or
[class]="'theme'" // use string 'theme'

[] is a way to bind the data between ts and HTML, so in this case, the theme is a variable, on the other side container is a direct property

what you understood about class is right, where coming to [class], based on the value, class will be applied to that element. if the value is true or some value then that class will be applied to that element or else it will ignore that class. so basically you are using a specific class for some functionality and not using it for another
eg: <div [class.classOne]="true"></div> // now div element will have classOne class because result is true or some value.
references for better understanding about classes:
https://angular.io/api/common/NgClass,
Difference between [ngClass] vs [class] binding

Related

*ngIf causing custom directive to not work properly

A custom directive applied to both components(1/2)-in-spotlight is not working properly when using *ngIf. The issue resolves when I remove the *ngIf and one of the components that would not show in the current situation/"mode".
In the HTML file using the component (original):
<div>
<div>
<div>
<div>
<component1-in-spotlight *ngIf="mode===OptionOne"></component1-in-spotlight>
<component2-in-spotlight *ngIf="mode===OptionTwo"></component2-in-spotlight>
</div>
</div>
</div>
</div>
I found 2 solutions but both aren't effective or proper.
Duplicating the surrounding parent/grandparent components (placing the second case in an <ng-template #elseBlock>) and applying ngIf-else to the top most component (in the oversimplified example, a div) works. But, I'd have a lot of duplicate code and is a terrible solution.
Option 1 (to illustrate since it might be a bit confusing for some). In the HTML file using the component:
<div *ngIf="mode===OptionOne"; else myElseBlock">
<div>
<div>
<div>
<component1-in-spotlight></component1-in-spotlight>
</div>
</div>
</div>
</div>
</ng-template #myElseBlock>
<div>
<div>
<div>
<div>
<component2-in-spotlight></component2-in-spotlight>
</div>
</div>
</div>
</div>
</ng-template>
Using [hidden] on the 2 components instead of *ngIf seems fine. But there is never a case where the hidden component will be toggled to visible, it's decided upon creation and stays using either of the 2 components until it's destroyed. So, it should just only have one of the 2 components in DOM. Not just hiding it. Plus, that means flipping the logic--[hidden]="mode!==OptionOne". For now, it's just 2 options and seems unlikely more would be added, but I can't guarantee that.
--
It may seem like these 2 components are the same, so why not just have 1 component and pass in the mode and let the logic decide within the TS file of that component? Well, they both have different services that are injected into the constructor for the component. I was trying that before finding out and remembering that I can't use this before calling super() to decide which service to send up to the base class the component is extending.
Merging the 2 components and using #Input to get the "mode":
In the HTML file using the component:
<div>
<div>
<div>
<div>
<component-in-spotlight-merged [inputMode]="mode"></component-in-spotlight-merged>
</div>
</div>
</div>
</div>
In the component-in-spotlight-merged TS file--what I tried to do:
export class ComponentInSpotlightMergedComponent extends MyComponentBaseComponent {
#Input() inputMode: MyEnumType;
//...
constructor(
myService1: MyService1,
myService2: MyService2,
){
if(this.inputMode === Option1){
super(myService1);
}
else{
super(myService2);
}
}
//...
}
Using [hidden] can be for a quick fix, but is there a proper way to fix this?
Edit:
Not working meaning: It's a custom directive for tabbing focus between elements and the hotkey logic is binded here. Somehow the hotkey works but the focus is not working as it expected and none of my console.log() are outputted.
Angular 9+
You can use Angular NgSwitch directive as shown below.
<div [ngSwitch]="mode">
<!-- the same view can be shown in more than one case -->
<component1-in-spotlight *ngSwitchCase="option1">...</component1-in-spotlight>
<component2-in-spotlight *ngSwitchCase="option2">...</component2-in-spotlight>
<!--default case when there are no matches -->
<some-element *ngSwitchDefault>...</some-element>
</div>
The fix was to use setTimeout(() => myCallbackFn(), 0); (on my hotkey bind function that is called in ngAfterViewInit in a component class down the line--a view grandchild?).
I was in a rabbit hole of reading other stackoverflow questions and found How do I combine a template reference variable with ngIf? where a comment mentioned that ngIf takes a tick of time to evaluate. I eventually searched and found How to check whether ngIf has taken effect.

Angular - CSS properties of added class not showing

I'm appending a childitem div to another div inside the same angular component. Then I assign a class to it. (using class list) It succesfully inserts the element and also adds the class to it but non of my css class properties are applied to it.
If I add the element manually inside my html code (including the class attribute) the element is shown correctly.
Why is this happening?
Typescript code:
let parent = document.getElementById('playingfield');
let cactus = document.createElement('div');
cactus.classList.add('cactus');
parent.appendChild(cactus);
HTML code of manually inserting the div:
<div class="cactus"></div>
To apply the runtime css into your html you need to use :host feature of angular.
In your .css or .scss file set css by this way.
:host ::ng-deep .cactus{
// Your css hear
}

AngularJS UI: how to apply my css class to overwrite the original css class of ui grid

As the title says, for example, I want to create a CSS class named myViewport to overwrite ui-grid-viewport (ui-grid).
This should have been discussed several times here. You can disable the horizontal bar with enableHorizontalScrollbar option. I don't think you would require css to achieve this unless you are trying out something different.
$scope.grid = {
enableHorizontalScrollbar: 0
};
It can take any one of the following values:
0 = disable;
1 = enable;
2 = enable when needed;
And note that you would need to pass the uiGridConstants to your controller.
You shall also check this github repository for more info.
https://github.com/angular-ui/ui-grid
I find a solution it's CSS element>element Selector, I add an id to parent element for example:
<div id=""test>
<div>
<div class="ui-grid-viewport(object)">...</div>
</div>
</div>
in the style.css
the name of class should be div#test >div> .ui-grid-viewport{}
this is a solution not simple, because I should find the position of ui-grid-viewport.

Angular2 Html Templates

Is there a way to call a component selector from another html template. For instance:
#Component({
selector: 'reports',
templateUrl: 'reports.html'
})
Can I call that selector "reports" from within another templateUrl? I'm trying to split out my html into separate files in order to make it more manageable. I know how to set it up like <reports></reports> in the html. I'm not sure how I would set this up or call it per say from within the modules.
When you specify a selector, you are basically defining a custom HTML element. So you can use it in any other template in the application as you've shown: <reports></reports>.
Angular modules provide the "template resolution environment". So you need to ensure that the component containing the "reports" selector is declared in the same component as any template that uses it, or is "pulled in" by way of an Angular module import.
I have an example here: https://github.com/DeborahK/Angular2-GettingStarted/tree/master/APM%20-%20Final Check out the star.component.ts.
selector: "[reports]"
selector: "[reports]"
I think your split your html page sub pages, it's very easy.
<body>
<div clss="ui container">
<reports></reports> //the reports page view render hear,just add
this component class in NgModules, it will works
</div>
<div clss="ui container">
<reports-list></reports-list> //you can add another file also same
</div>
</body>

Why doesn't individual styling of a react component instance work?

I'm using the following instance of a react component in a view:
<Jumbotron>
Lot's of important content
</Jumbotron>
I want an individual style (i.e. a different background image for this instance. So this doesn't work:
<Jumbotron className="individual">
Lot's of important content
</Jumbotron>
Wrapping the instance in a div also doesn't work. How can I do this with simple markup and CSS so that I can simply style the individual class in CSS? AFAIK properties won't help to customize instances...
You can either pass in the style attribute or you can pass through the className attribute in the same way
<Jumbotron className="background--black">
And have your component like this -
const Jumbotron = ({className}) => {
<div className={className}>
Here is the jumbotron
</div>
}
export default Jumbotron
And import a css file that has that class in, if you're using className. But I would probably recommend just using style attribute if it's a one off.