dynamic switching of two styles.css file in one angular application - css

I have to merge two angular applications into one major angular application. Hence, now i am having two styles.css files in one angular application. On running this application after merging both, css is going completely for the angular application.
Is there any way by which we can call this two style.css files dynamically depending on the requirement? Or I need to check each class one by one?

I recommend you to use two different layouts, each one is a component, so each one has a different set of styles. That it's really easy wit angular router.
In your routing module:
// Layout 1
{
path: '',
component: Layout1Component,
children: [
{ path: 'pageL1_1', component: PageL1_1Component },
{ path: 'pageL1_2', component: PageL1_2Component }
]
},
// Layout 2 routes goes here here
{
path: '',
component: Layout2Component,
children: [
{ path: 'pageL2_1', component: PageL2_1Component },
{ path: 'pageL2_2', component: PageL2_2Component }
]
},
In your app.component.html:
<router-outlet></router-outlet>
The layouts templates has to include the element to in order to show child navigation componets.
IMPORTANT: Each layput controller should disable view encapsulation so styles applies ti child components:
#Component({
selector: 'app-layout_1',
templateUrl: './layout_1.component.html',
styleUrls: ['./layout_1.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class Layout1Component implements OnInit {
...
}

Related

import additional scss as theme on demand in angular

I am implementing admin panel for my application and the same has been lazy loaded, but I would like to speparate scss for admin panel. Say:
Public Portal
ecom-blue.scss
Admin Panel:
ecom-blue.scss
ecom-admin.scss
As of now I am importing both the CSSs in theme.scss like this way:
#import '~#angular/material/theming';
#include mat-core();
#import "themes/ecom-blue";
#import 'themes/ecom-admin';
$background: map-get($ecom-theme, background);
$foreground: map-get($ecom-theme, foreground);
which is further imported in app.scss this way:
#import "scss/variables";
#import "scss/themes";
#import "scss/views";
In angular.json
"styles": ["src/assets/styles/app.scss",
"node_modules/font-awesome/css/font-awesome.css"]
The problem with this approach is that the style.css (compiled file) will be having both the themes whereas I just want rent of the css to be included where my admin router layout is activated as per lazy loading.
may I know the best approach for this so that style.css file should be divided as per module and also to be loaded when required.
Edit:
This is how my router component look like:
#Component({
selector: 'app-auth-layout',
templateUrl: './auth-layout.component.html',
styleUrls: ['./../admin-layout.scss'],
// encapsulation: ViewEncapsulation.None
})
and this is how it is lazy loaded:
{
path: '',
component: AuthLayoutComponent,
children: [
{
path: 'admin4556',
loadChildren: () => import('./views/admin/admin.module').then(m => m.AdminModule),
data: { title: 'Admin', breadcrumb: 'Admin'}
}
]
},
UPDATE: If you will use ViewEncapsulation.None, yes, this allows you to apply base styles for children components, for example, if you style tag <p> in the parent component, the same style for <p> will be applied in the children component. BUT this is not the best practice. So if you sometimes will want to change your style in the child you need to add !important or add more points to your element to make it more specific. Will be better if you move out all common styles to BaseTheme or even styles.scss, and leave some specific styles inside lazy-loaded components. '' helps if you want to split your routes by different style areas if you have only one area base style you can go with styles.css only.
ORIGINAL:
If you want to apply some common style, for example, to user and admin components, and at the same time have some styles lazy-loaded specifically to each of them, you can do it with '' route. This is not some specific route, it's just skipped and goes further to children, but this allows us to add additional styles before it. It looks like this:
{
path: '',
component: BaseTheme, //base style
children: [
{ path: 'adminpanel', loadChildren: () => import('./adminpanel/adminpanel.module').then(m => m.AdminPanelModule) } //inside we add specific style
{ path: 'userpanel', loadChildren: () => import('./userpanel/userpanel.module').then(m => m.UserPanelModule) } //inside we add specific style
]
}

Angular 4 - Not use styles from angular-cli.json

I have an angular 4 application where I have the global styles and scripts in angular-cli.json. Then I worked separately on the Landing page. After I turn the landing page into an angular component, I add all its styles in angular-cli.json as well. And now my landing page's bootstrap conflicts with global bootstrap in node_modules and my application breaks.
Currently angular-cli.json looks like this:
"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
"./dist/css/landing/bootstrap.min.css",
"./dist/css/landing/font-awesome.min.css",
"styles.css",
"./dist/css/AdminLTE.min.css",
"./dist/css/skins/_all-skins.min.css",
"../node_modules/froala-editor/css/froala_editor.pkgd.min.css",
"../node_modules/froala-editor/css/froala_style.min.css"
],
This is in landing.component.ts:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-landing',
templateUrl: './landing.component.html',
styleUrls: ['./landing.component.css']
})
export class LandingComponent implements OnInit {
constructor() { }
ngOnInit() { }
}
I am almost missing my deadline, I can not resolve the conflicts between two huge css files. I was wondering if I could keep my Landing Page styles separated from application styles. Any help will be largely appreciated. Thank you.
You could try encapsulate your landing page as follows.
ViewEncapsulation.Native will wrap your component and its styles within a shadow root. Change your component style file to scss and import those styles in component style file and delete them from .angular-cli.json.
#Component({
selector: 'app-landing',
templateUrl: './landing.component.html',
styleUrls: ['./landing.component.scss'],
encapsulation: ViewEncapsulation.Native
})
export class LandingComponent implements OnInit {
constructor() { }
ngOnInit() { }
}
landing.component.scss
#import '<path-to-dist>/dist/css/landing/bootstrap.min.css';
#import '<path-to-dist>/dist/css/landing/font-awesome.min.css';
When you inspect DOM, you'll see app-landing as encapsulated.
Edit
Alternatively, you can use ViewEncapsulation.Emulated which is default (you do not have to set it within metadata). What this will do is to create custom attributes with all the styles and add those attributes to your markup as well. Shadow DOM may not be supported in some browsers. Try both and if Emulated works for you, use that.

angular2 component styleUrls not working correctly

I have an angular2 component:
#Component({
providers: [
FlowsheetService,
SubscriptionService
],
moduleId: module.id,
selector: 'flowsheet',
templateUrl: './flowsheet.component.html',
styleUrls: ['./lastRow.css']
})
lastRow.css in the same directory as the component file contains:
.yellow {
background-color: yellow;
}
in my third party control there is an API that needs a css class name as return value.
that function is as follows:
function className() {
return 'yellow';
}
I don't see anywhere showing up in yellow in my 3rd party control.
Am I coding this correctly in general?
This syntax:
styleUrls: ['./lastRow.css']
Defines a style only for the template associated with this component. Is the function you defined within the component? If not, the style cannot be defined in this manner. You need to define the style for the app instead.
The Angular documentation here: https://angular.io/docs/ts/latest/guide/component-styles.html goes through how to define styles for the application instead.

How to bundle Angular 2 component css?

In my application for angular 1 I used to bundle all of the css in library.css and application.css. While this can be done with angular 2 the same way for ordinary css, there is a new feature that allows a "component css". As far as I can see Angular just downloads the css file and then processes it to add some id's to not interfere with each other.
Now if I just bundle all of these css'es Angular just won't be able to find them. Is it possible at all to do bundling of component css? Perhaps a similar way to bundling HTML exists, where HTML is really put into .js as string?
I managed to achieve this with webpack and a special angular2-template-loader plugin. This is the config from webpack 2:
module: {
rules: [
{
test: /\.ts$/,
use: ['awesome-typescript-loader', 'angular2-template-loader']
}
Basically what it does, it replaces templateUrl and styleUrls with inline template and styles and just stores them in a string as a separate "module".
How does it work
The angular2-template-loader searches for templateUrl and styleUrls
declarations inside of the Angular 2 Component metadata and replaces
the paths with the corresponding require statement. If keepUrl=true is
added to the loader's query string, templateUrl and styleUrls will not
be replaced by template and style respectively so you can use a loader
like file-loader.
The generated require statements will be handled by the given loader
for .html and .js files.
P.S. The whole set up can be found in Anagular tutorial.
These are the combination of the loaders that does the trick if you have
templateUrls and styleUrls
loaders: [{
test: /\.ts$/,
loaders: ['awesome-typescript-loader', 'angular2-template-loader']
},
{
test: /\.html$/,
loader: 'raw-loader',
exclude: [root('src/index.html')]
},
{
test: /\.css$/,
loader: 'to-string-loader!css-loader'
}
],
and in the code
#Component({
selector: 'my-app',
templateUrl: 'sub.component.html',
styleUrls: ['app.component.css']
})
export class AppComponent {
}

How to do multiple routing (router-outlet) in angular2 RC4?

I am finding problem while multiple routing, its loading in single router-oulet how to tell the component to load in specific named outlet? I found out that there is a property in RouterConfig from which i can use outlet to name the router-outlet but i don't know to link it with HTML.
https://angular.io/docs/ts/latest/api/router/index/RouterConfig-type-alias.html
Define a UI with two router outlets..
<div>
<router-outlet></router-outlet>
<router-outlet name="aux"></router-outlet>
</div>
Then have a router config that routes a component into that space.
[{
path: 'parent/:id',
children: [
{ path: 'a', component: MainChild },
{ path: 'b', component: AuxChild, outlet: 'aux' }
]
}]
NOTE: the parent route's id parameter will be provided to both children. Remove it if you aren't providing an id.

Resources