In angular we could do:
template: `<ng-container #c></ng-container>`
or:
template: `<template #c></template>`
To create a view container that is hidden when the template is rendered.
Is there a difference between using ng-container over the html template alternative? I'm guessing Angular has to have it's own template containers like ng-template or ng-container since use of the raw html template element could break non browser based runtimes, like mobile clients, etc.
The <ng-container> is always rendered, but does not represent a DOM element. It is still attached to the component's view.
The <ng-template> will only be rendered if it is explicitly requested.
Here's a good reference on the subject:
http://nataliesmith.ca/blog/2018-05-01-ngtemplate-ngcontainer-ngcontent/
To create a view container that is hidden when the template is rendered.
Always use <ng-template> when possible. The <ng-container> is for grouping DOM elements together. For example; when you need to apply a *ngIf to many <td> elements, because you can not use a <span> around <td>.
Related
QuerySelector is part of typescript or javascript. Can I use this in my angular application Which one needs to use instead of QuerySelector in angular application. Why I am asking, Suppose generating dynamic HTML on that condition I want to handle some event on the dynamically generated HTML.
On that condition, querySelector is very easy. But some people are telling like do not to use quesrySelector that is not good practice. So, How to handle these issue?
document.querySelector(".myclass");
document.querySelector("ul").querySelectorAll('li');
In order to dynamically render content you can use structural directive like *ngIf
<div>
<p *ngIf="displayElement; else showThis">Content</p>
<ng-template #showThis>
else content
</ng-template>
</div>
querySelector it's not a good practice in Angular.
Instead of using querySelector or similar from there, a declarative way can be used instead to access elements in the view directly:
<input #myname> // html
#ViewChild('myname') input; // add this in ClassComponent
ngAfterViewInit() {
console.log(this.input.nativeElement.value); // Input will be available in this lifecycle
}
When dealing with "flash of uncompiled content" in Vue, the split seconds (or more) where the page is loading and you see the {{ Mustache }}, I've seen people using both v-text and v-cloak.
With v-text, the documentation says:
Updates the element’s textContent. If you need to update the part of
textContent, you should use {{ Mustache }} interpolations.
With v-cloak:
This directive will remain on the element until the associated Vue
instance finishes compilation. Combined with CSS rules such as
[v-cloak] { display: none }, this directive can be used to hide
un-compiled mustache bindings until the Vue instance is ready.
So it sounds like if I don't need to update the textContent, I can use either to achieve the same result. Besides that, what is the difference between v-text and v-cloak? And is one better than another when it comes to hiding {{ Mustache }}?
v-text is for setting the entire textNode of an element equal to some value. It's intended to be used in place of {{}} when you are wanting to affect all of the text content. v-cloak is however meant for hiding an element until compilation is complete.
I have a user-configurable layout where I believe I would need to change nesting of elements per configuration. I don't want multiple templates, as this would be a chore to maintain, but I would like to know if there is some way in Angular 2 to define a parent element whose child elements will display weather or not the parent element is displayed. So if I have:
<parent>
<child />
</parent>
I would like to use some sort of toggle to remove the parent element from the display list without losing it's child. So upon toggling off, child would become a child of parent's parent.
Is that even possible?
If parent is just an HTML tag, this can be accomplished indirectly using CSS classes that are applied conditionally.
For example, if parent is a <div>:
Template:
<span [class.myDivClass]="condition">
<child />
</span>
CSS:
.myDivClass {
display: block;
}
If parent is an Angular component, it may be easier just to add an input to it that disables its functionality instead of trying to un-nest it.
Alternately, it might be possible to create a directive that could have this type of effect.
I like to think of Angular components as element directives. Given a component called hero I can use it in the parent template like this:
<hero myparam="something"></hero>
I'd like to use the hero element as a component-managed container, with the component being in charge of the whole element.
EXPECTED
Here's what I hope to get out of the binding from above:
<hero id="component123" class="alien" custom="foo">text</hero>
My custom component transforms the given element and uses it as it sees fit.
ACTUAL
However, it seems the component can only render its template inside the hero element. Best I can get is:
<hero myparam="something">
<div id="component123" class="alien" custom="foo">
text
</div>
</hero>
I feel this is bad because the hero element is not actually the hero, but merly a wrapper for the actual hero. This mixes up the semantics and creates unwanted extra elements.
Is it best practice in Angular to use components as pure wrappers and putting the actual components inside?
Here's an official sample to play around with:
https://plnkr.co/edit/NKjCDS8OEngYHNrBmC5O?p=preview
I like to think of Angular components as element directives.
A component could be thought of as a special kind of directive that updates a template. If you want to change attributes, use an actual directive (attribute directive)
My custom component transforms the given element and uses it as it
sees fit.
When you talk about transforming, you want directives, not components.
In order to to get Polymer's data-binding without creating a custom element, I am using the "dom-bind" template helper. Later on, I am going to need to access the nodes inside the template so I can use masonry.js
to create a grid out of the data.
Here is the my template that is inside the main document:
<!-- Skills -->
<template is="dom-bind" class="careerSkills_consumer projects_consumer" id="resume-container">
<page-section id="resume">
<section-title>Skills and Projects</section-title>
<section-content>
<template is="dom-repeat" items="{{careerSkills}}">
<skill-category class="grid-item" title="{{item.header}}" skills="{{item.skills}}"></skill-category>
</template>
<project-showcase class="grid-item" projects="{{projects}}"></project-showcase>
</section-content>
</page-section>
</template>
The data itself is provided elsewhere and is irrelevant. The issue I am running into is that both dom-bind and dom-repeat seem to create local dom and put the result inside of it.
To create my grid, I need to access both the container for the grid, which will be the section-content element and the grid items, which are the skill-category elements inside the dom-repeat template.
If they all resided in the same document, I think could do (I am new to masonry, so this might not actually work):
document.addEventListener('WebComponentsReady', function () {
$('#resume section-content').masonry({
columnWidth: $('#resume skill-category')[0],
itemSelector: 'skill-category',
isFitWidth: true
});
});
But the queries don't seem to work because presumably the elements I need are hidden away from the main document in the shadow dom.
I was able to get access to the content inside #resume-container via:
Polymer.dom(document.querySelector('#resume-container')).node.content
However, I still can't get to the skill-category elements in the dom-repeat. This is getting kind of pedantic and I'm not even sure if it will work when masonry tries to do the positioning.
Is there a better way to go about this?
To be clear, this question is about how to properly gain reference to the content distributed inside of template helpers, but I would also appreciate any general advice to using polymer to do this sort of thing, where a custom element isn't exactly what I'm looking for since I'm only going to use the template in one spot and shadow dom is more hassle than help, but I need the data-binding.