I started learning angular 5 3 days ago so I'm quite new at it. I also use angularJS and React to develop applications and I think I don't understand how angular 5 components fully work. If I create for example a custom button that has a custom text inside (I'm not saying this should be done this way but it's a simple example that shows my point) like this:
<app-button>
<app-text>
My Text
</app-text>
</app-button>
The rendered DOM results in:
<app-button>
<button>
<app-text>
<span>
My Text
</span>
</app-text>
</button>
</app-button>
which is unreadable, I wanted to know if there's a way to remove this wrapping elements and just place the components layout replacing the tags resulting in the following structure:
<button>
<span>
My Text
</span>
</button>
If there's no way of removing them what are your suggestions? thanks!
How to remove wrapper elements but keep text content as it is using jQuery? jQuery provide several methods for performing this operation such as wrap (), wrapAll (), unwrap (). Using jQuery wrap () to wrap specified HTML elements around each selected element. Element :- It is a mandatory parameter. Function (index) It is an optional parameter.
Using jQuery wrap () to wrap specified HTML elements around each selected element. Element :- It is a mandatory parameter. Function (index) It is an optional parameter. This example will demostrate you how use wrap method to selected html elements. Wrap elements inside a div using jQuery Wrap method. Hello Programmers!
In this snippet, we’re going to demonstrate how you can disable word wrapping in HTML. Actually, this can be done with a few steps using some CSS properties. To prevent the text from wrapping, you can use the CSS white-space property with the “nowrap” or “pre” value. In this snippet, you can see examples with both of them.
Think of the wrapper element as a <strong>, <span>, <div> or whatever you need to wrap something in. Then think of the el tag as the thing that you need to put inside that <strong> tag. The function verifies that this is an element and that it has a parentNode.
Angular components are directives with templates. According to this:
Directive configuration @Directive({ property1: value1, ... })
selector: '.cool-button:not(a)' Specifies a CSS selector that identifies this directive within a template. Supported selectors include element, [attribute], .class, and :not().
So component selectors can be also attribute selectors. For your example, instead of writing this:
parent.component.html:
<app-button>
<app-text>
My Text
</app-text>
</app-button>
write this:
parent.component.html:
<button app-button>
<span app-text>My Text</span>
</button>
where :
app-button.component.ts
...
selector: '[app-button]',
template: `<ng-content></ng-content>
...
app-text.component.ts
...
selector: '[app-text]',
template: `<ng-content></ng-content>`
...
this would be rendered as you expected:
Update after your comment about styling those buttons:
To style the buttons from inside the button component, and set class in parent component, use :host-context
pseudo-class. It is not deprecated and works well
button.component.css
:host-context(.button-1) {
background: red;
}
:host-context(.button-2) {
background: blue;
}
app.component.html
<button app-button class="button-1">
<span app-text>My Text</span>
</button>
<button app-button class="button-2">
<span app-text>My Text</span>
</button>
Here is the DEMO
I had a similar issue. I'll provide my solution in case someone else has the same problem.
My component should be able to be used either within other components or as a route from <router-outlet></router-outlet>
. When I used the selector as an attribute [my-component]
things worked perfectly provided it was used within other components. But when created by <router-outlet></router-outlet>
a <div>
were created automatically.
To avoid that, we can simply use multiple selectors, and consider that the selectors can be combined.
Consider this: I want my component to use the attribute my-component
and if it ever should be created by the <router-outlet></router-outlet>
it should be wrapped in a <section></section>
. To achieve this simply use:
@Component(
selector: 'section[my-component], my-component',
...
)
The result will be, if used inside another tag:
<whatevertag my-component>
... component content ...
</whatertag>
If used as a route:
<section my-component>
... component content ...
</section>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With