Use styling for ng-content from template component - html

I've created a template case component which I'm intending to use for multiple cases. To use the component as a template, I used ng-content select="".
It works fine, but not completely as desired. For example:
I have a div with a background image, its style is being configured inside of the template component:
<div class="front-image min-vh-100 min-vw-100" [style.transform]="'scale(' + scale + ')'">
</div>
To make this usable as a template, I replaced the given code with: <ng-content select=".front-image"></ng-content> and used the template inside of another component like this:
<app-case-template *ngIf="cases[3] as case">
<div class="front-image min-vh-100 min-vw-100" [ngStyle]="{ 'background-image': 'url(' + case.image + ')'}"
[style.transform]="'scale(' + scale + ')'">
</div>
</app-case-template>
How can I achieve the template to always get its styling from the template component - right now I had to declare its styling inside of the new component to get it working. Additionally [style.transform] stopped working.
Is there something like a bypass?

You may be going about this the wrong way. I'll try to outline a good way to do it. First, have a directory for your templates:
templates
- template.component.css (generic styling)
- template.component.html (your markup)
- template.component.ts (your ts/js)
Set up your template.ts for use:
import {Component} from '#angular/core';
#Component({
selector: 'template-component',
templateUrl: 'template.component.html'
styleUrls: ['./template.component.css']
})
export class TemplateComponent {
}
Register it in your component.module.ts (or whatever you may have called it):
...
import {TemplateComonent} from './templates/template.component';
...
const exportedComponents = [
SvgIconComponent
]
If needed, have your shared.module.ts export it:
import {ComponentsModule} from './components/components.module';
...
exports: [ComponentsModule]
Now you can use it like it's a custom HTML tag (your selector):
<template-component class="template"> </template-component>
Now it will always grab the css styling from itself, but you can stick a custom class in that tag as I have done, or call it like this from your main component's style page:
template-component {
margin: 10px;
background-color: grey;
}
There's a lot you can do including setting #Input() tags in your template that can be called from your HTML tag. You can also use Angular bindings to dynamically enter values or text into it. Many options here.
Note: instead of calling them templates, consider calling them shared components, or shared modals (if so). Have a directory called shared > components and have a custom-name directory with the like in there for organization.

Related

Create a master table component and add child columns dynamically in angular

Good morning everyone !
So have to create an application that displays many tables that all look the same (except their columns of course and the objects inside).
I have a master table component which can be summarized by:
<master-table>
<!-- here I define the master table style, pagination, etc etc
which is the same everywhere -->
</master-table>
In the master table component TS file I have basically options that are relevant for every page where this kind of table should be displayed, such as filterDate, clearSelection etc etc etc nothing very special.
The point is, I don't want to repeat this code every where because it is not necessary, so my idea was to create several component that would extend the master table component.
It works fine for the typescript values, but I am stuck with the HTML.
In my master table HTML I would like at some point some kind of placeholder something like this:
<master-table>
<standard-for-all-table></standard-for-all-table>
<!-- insert here child columns -->
</master-table>
In the components that extends my master table I was imagining then something like:
<!-- child component -->
<master-table></master-table>
<child-column>column definition</child-column>
Doing this would allow me to define only the columns in the child components HTML and they would be added automatically to the parent HTML at runtime...
Any idea how to do this ?
Cheers and thanks !
Basically you have to create your main master-table component and your generic list chid-column component and insert it in your parent html template structure.
I've edit the final part hope in a better understanding way...
Then you can structure your child component to contain all the properties you need and thanks to *ngIf show only the properties you return from your provider methods i.e. getClients(), getUsers(), getHouses(), also thanks to the #Input decorator you can inject this data directly from the parent to the child and create many components you want with just a change of the data.
So in your parent you can have something like
import { Component } from '#angular/core';
import { MY_DATA_FROMP_ROVIDER } from './mydata/provider';
#Component({
selector: 'master-table',
template: `
<ul>
<child-column *ngFor="let item of items"
[item]="item">
</app-hero-child>
</ul>
`
})
export class MasterTableComponent {
items:any
constructor(public data: MYDATAFROMPROVIDER) {
this.items = MYDATAFROMPROVIDER.myGetMethod();
}
And in your child
import { Component, Input } from '#angular/core';
import { INTERFACE } from './mydata/interface';
#Component({
selector: 'child-column',
template: `
<div *ngIf="item.id">{{item.id}}</div>
<div *ngIf="item.name">{{item.name}}</div>
<div *ngIf="item.address">{{item.address}}</div>
<div *ngIf="item.phone">{{item.phone}}</div>
`
})
export class ChildColumnComponent {
#Input() item: INTERFACE;
}
If you want to go deeper: Component Interaction
This guide is from official angular page Here
Here is the live sample of it
Not sure if these links could help.
But I actually worked on a project where we want to dynamically loading Child component into a Grid(Parent component).
And later on we can pass any component with different view inside the Grid
Guess that pretty close to your goal.

How to dispaly diffrent background color each page with Angular 5?

I am new to Angular, I need to change the background-color of the body tag. I created a project in Angular with multiple pages.
Ex:
Login / Home / About / Service / Contact
I need to display a different background-color on each page.
But here actually, the body tag is common for all pages so I'm unable to change the `background-color in CSS?
you could try changing it during the Component ngOnInit lifecycle,
something like this
ngOnInit(){
document.body.style.backgroundColor = 'red';
}
inside your component code
Or you could also try changing ViewEncapsulation, but it will change it for all the component styles, so it could lend you to unexpected things.
Something like this
#Component({
selector: "app-theme",
templateUrl: "./theme.component.html",
encapsulation: ViewEncapsulation.None,
styleUrls: ['./theme.component.scss']
})
As you asked in your comment, you want to edit body classes as well, so I think you're going for the first option I wrote.
It could be different based on how many classes you want to handle. I'll write down the example for just one class
ngOnInit(){
const body = document.body;
body.className = '';
body.classList.add('classname');
}
If you need to handle more classes, you will need to edit your code, to remove just the classes you don't need, instead of all of them

I called a css that belong to another html. how is that?

I work on the Ionic 3 with angular 4. Each HTML file has its CSS file. Sometimes, I called in the HTML a case that is linked to another HTML.
I understand that this CSS class is injected into the main.js
Example of arboressance:
page1.hmtl
page1.css
page1.ts
page2.html
page2.css
page2.ts
I called a CSS from page1.css to page2.html.
My question is : Is this behaviour linked to the order of the ts declared on the app.module.ts?
page1 {
.marginForEmplacement{
margin-left: -5px!important;
}
}
page2.html
<div class="marginForEmplacement"> some text </div>
Why do you need to complicate the situation?That is why Ionic team has given the app.scss file. Just put your shared or global CSS details on that file and use wherever the places throughout the app. So simple no?
app.scss
.marginForEmplacement {
margin-left: -5px;
}
page2.html
<div class="marginForEmplacement"> some text </div>
The question isn't entirely clear but an Angular component can have multiple style sheets imported into a component, see styleUrls. This would take precedence over the global stylesheets. This is just an example but could be a cause of the problem. See documentation here.
#Component({
selector: 'app-root',
template: `
<h1 class="sheet1-h1-header'>Tour of Heroes</h1>
<app-hero-main [hero]="hero" class="sheet2-wrapper'></app-hero-main>
`,
styleUrls: ['./sheet1.css', './sheet2.css']
})
export class HeroAppComponent {
/* . . . */
}

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>

Does an Angular 2 '#Component' decorator always need an element name selector?

In this example, from the official Angular 2 docs, the decorator looks like this:
#Component({
selector: 'my-app',
template: '<h1>My First Angular App</h1>'
})
Example: would prefer not not have my HTML code littered with non-standard elements, and would prefer something like (NB: ng-angular is only an example I would like to see):
import { Component } from '#angular/core';
#Component({
template: '<h1>Wait! Bloody wait some more.</h1>'
})
export class ListComponent { }
and used something like this:
<div ng-component="List"</div>
Or is the a Component decorator like this used only when you want to create a new HTML element, and then stick to a plain Listcontroller for the div in my example above?
A selector is not always needed eg. you have a top component of a module that is loaded by router and displayed in
selector is needed for any other type of component. otherwise angular wouldn't know what component it should render.
I haven't heard about attribute "ng-component"
[EDIT]
kit effectively answered correctly in his/her first comment:
You have to create an element that would enclose your template however it doesn't have to be a new HTML element because selector can be a element, [attribute] or class, eg.
<div test>
could be an element for component with selector: '[test]'
A component is a new HTML element, something like <my-component>Hello</my-component>.
I think what you want is a directive.
An Attribute directive changes the appearance or behavior of a DOM element.
So you can do something like <div makeItBlue>Blue stuff</div>
Just to elaborate: The selector can be a standard CSS-selector, so your HTML can be non-angular-centric.
Example:
#Component({
selector: 'div.player-list',
...
})
export class PlayerList {
}
will match <div class="player-list and-possibly-some-other-classes">...</div> (i.e. replacing the div with your angular template)