Custom user template for a component in Angular 2 - javascript

I've got a component that has it's default template:
import {Component} from 'angular2/core';
#Component({
selector: 'my-component',
template: `
<div class="container">
<div class="content">
<div *ngIf="contentRef.childNodes.length == 0">DEFAULT: <b>{{contentData}}</b></div>
<div #contentRef><ng-content select=".content"></ng-content></div>
</div>
</div>
`
})
export class MyComponent {
contentData = "DATA";
}
I would like a user to be able to specify his own templates for some parts of the component when using it. So it can be written as follows:
import {Component} from 'angular2/core';
import {MyComponent} from './my.component';
#Component({
selector: 'my-app',
directives: [MyComponent],
template: `
<my-component></my-component>
<br/>
<my-component>
<div class="content">
CUSTOM: <i>{{contentData}}</i>
</div>
</my-component>
`
})
export class AppComponent { }
It produces the following markup:
<my-app>
<my-component>
<div class="container">
<div class="content">
<!--template bindings={}--><div>DEFAULT: <b>DATA</b></div>
<div></div>
</div>
</div>
</my-component>
<br>
<my-component>
<div class="container">
<div class="content">
<!--template bindings={}-->
<div><div class="content">
CUSTOM: <i></i>
</div></div>
</div>
</div>
</my-component>
</my-app>
So the component's 'contentData' property is not rendered within the custom template. Is it possible to provide the custom template with a specific binding context somehow? Or is there a better way to implement the case with a custom user template?

How to realize website with hundreds of pages in Angular2 shows an approach.
This is no official solution and to me it currently looks like this is likely to break before the final release.
Angular2 has a strong tendency to statically building and resolving the bindings.
Either you can work with DynamicComponentLoader or you don't build on Angulars binding features for dynamically added content.

Related

Angular, Inject an Input from a Component into my header

I want for my Pages induvidually to inject different components from other Pages/Components into the header. For example I want to inject an Input search Field from my content-component into my header Component. I tried with ng-Content, but this only duplicates my header in my HTML. The problem is my header is not in each Component individually, its in my app.component.
My Header Component:
<div class="header__sub">
<div class="header__title header__title--sub">
<h2 class="title title--medium">{{ subtitle }}</h2>
</div>
<div class="header__search">
<!-- Here should be my Input field -->
<ng-content></ng-content>
</div>
Component from I want to inject the input field:
<app-header>
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Search" />
</mat-form-field>
</app-header>
....
App-Component.html:
<mat-drawer-content>
// The header
<app-header-sub>
</app-header-sub>
<div class="content__inner">
// My Content
<router-outlet></router-outlet>
</div>
</mat-drawer-content>
How can I inject from each Component individually a different tag into the header (with functionalities)?
You can use it like that:
Child component
<div class="header">
<ng-content select="[name]"></ng-content>
<div>
Parent component
<app-header>
<div name>Hello World</div>
</app-header>
Demo for your reference: https://stackblitz.com/edit/ng-content-select-attribute
Or look here: Multiple ng-content

Can I use component inside another component in Angular?

Something like this
<app-component1>
<app-component2></app-component2>
</app-component1>
I did't find about it in Angular docs. When I use component in component, it shows nothing
You need to add <ng-content></ng-content> in the template file for <app-component1> where you wish to include <app-component2></app-component2>.
For example, below could be the HTML file for the component1:-
<div>
<ng-content></ng-content> <!-- component 2 inserted here -->
</div>
Yes, You can nesting component
#Component({
selector: 'app-root',
directives: [MyChildComponent]
template: '<div><ChildComponent></ChildComponent></div>'
})
export class AppComponent {}
#Component({
selector: 'ChildComponent',
template: '<h2>Child component</h2>'
})
export class MyChildComponent {}
https://codecraft.tv/courses/angular/quickstart/nesting-components-and-inputs/

Does multislot transclusion works with Angular 2 components?

let's say I've got the following basic component with two slots:
// my-component.component.ts
#Component({
selector: 'my-component',
template: `
<div class="my-component">
<div>
Title:
<ng-content select="my-component-title"></ng-content>
</div>
<div>
Content:
<ng-content select="my-component-content"></ng-content>
</div>
</div>`
})
And into the second slot ('my-component-content') I want to insert regular Angular 2 component...
<div class="app">
<my-component>
<div class="my-component">
<div>
Title:
<my-component-title>
This is the Component title!
</my-component-title>
</div>
<div>
Content:
<my-component-content>
<some-regular-angular2-component></some-regular-angular2-component>
</my-component-content>
</div>
</div>
</my-component>
</div>
Where 'some-regular-angular2-component' is a selector of some Angular 2 component...
#Component({
selector:'some-regular-angular2-component'
})'
Problem is that 'some-regular-angular2-component' is never transcluded into ng-content second slot...Only regular HTML works for me...Of cource I tried to set 'some-regular-angular2-component' into [directives] of parent component, but Angular 2 component is not recognized inside of the ng-content...Or does this work for you?
You need to add <ng-content></ng-content> to the view (template) of <my-component-content> If <my-component-content> doesn't support transclusion, its children won't be shown. The <ng-content> tags in your code apply only to elements that match directly, but not their children.
Just to answer my question, yes, angular 2 transclusion supports inserting of Angular 2 components. I had stupid typo in the code.
Yes it does. It is now called content projection. See this example of a modal dialog with multiple slots.

How to use nested templates in Angular.js?

I have root selector:
<body>
<my-app>
Loading...
</my-app>
</body>
In him loaded component with template:
#Component({
selector: 'my-app',
template: `
<p>It is nested content:</p>
<div class="content">
<nested-selector></nested-selector>
</div>`
})
Now I want to download the content in nested-selector:
#Component({
selector: 'nested-selector',
template: `<p>{{content}}</p>`
})
export class Mycomponent{
public content = "qwerty12345";
}
As a result, appended in the end an string:
<nested-selector _ngcontent-rbv-2="">qwerty12345</nested-selector>
As a result, we get the following page:
<body>
<my-app>
<p>It is nested content:</p>
<div class="content">
<nested-selector></nested-selector>
</div>
<nested-selector _ngcontent-rbv-2="">qwerty12345</nested-selector>
</my-app>
</body>
Although page should look like this:
<body>
<my-app>
<p>It is nested content:</p>
<div class="content">
<nested-selector>qwerty12345</nested-selector>
</div>
</my-app>
</body>
Why is this happening? Why he creates a new selector? How to make it work properly?
EDIT:
I attached the main project files to uncover the essence of the problem:
https://plnkr.co/edit/DsDpXG72bjpyaWfPc1S0?p=preview
I'm pretty sure you HTML is invalid.
.
I tried to reproduce in this Plunker but it shows the desired behavior.

Angular 2 Components and bootstrap css grid placement

I'm using angular 2 to create a page using different components. My layout is kinda like this:
#Component({
selector: 'my-app',
template: `
<x-header></x-header>
<div class="col-md-1">
<x-sidebar></x-sidebar>
</div>
<div class="col-md-6">
<x-table></x-table>
</div>
`,
directives: [HeaderComponent, SidebarComponent, TableComponent]
})
export class AppComponent {}
that is my main component that gets loaded from the index.html - the other components contain the tags and css pertaining to their parts. I'm adding bootstrap.min.css in the index.html and I wanted the grid system to be applied to the whole page, so I could have the components fit together. Yet, this is the layout of the current page.
As you can see the table is being rendered from the start of the page, and it goes under the sidebar and the header. I'm not sure if it's important, but I plan to add a "toggle nav bar" button somewhere.
EDIT: My question is, why are the components fitting in together? Why is the table underneath the header and sidebar? Why isn't the bootstrap grid system working?
This seems more of a css issue.
Bootstrap grid system works like count of 12 meaning if you have two elements on the page in a block then if first element is col-md-4 then second should be col-md-8 to fit in horizontally.
#Bootstrap grid system.
In your case it might be possible at template:
#Component({
selector: 'my-app',
template: `
<x-header></x-header>
<div class="col-md-3"><!-- change to col-md-3 -->
<x-sidebar></x-sidebar>
</div>
<div class="col-md-9"><!-- change to col-md-9 -->
<x-table></x-table>
</div>
`,
directives: [HeaderComponent, SidebarComponent, TableComponent]
})
For header you have to inspect if that element is statically positioned.
You're missing the parent div with class "row", change the code to this:
#Component({
selector: 'my-app',
template: `
<x-header></x-header>
<div class="row">
<div class="col-md-1">
<x-sidebar></x-sidebar>
</div>
<div class="col-md-6">
<x-table></x-table>
</div>
</div>
`,
directives: [HeaderComponent, SidebarComponent, TableComponent]
})
export class AppComponent {}

Categories

Resources