Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular4: unable to use <ng-container> with component selector

Tags:

angular

in the past I had some problem with UI framework like Bootstrap and Semantic-UI. When I instantiate a new component in template it was breaking the style because Angular2 was adding elements in the DOM.

I resolved using and declaring the selector as "[component-selector]" in the component.

Now I've upgraded to Angular4 and if I use a component selector within a ng-container I obtain this error:

HierarchyRequestError: Failed to execute 'appendChild' on 'Node': This node type does not support this method.
Error: Failed to execute 'appendChild' on 'Node': This node type does not support this method.
    at DefaultDomRenderer2.webpackJsonp../node_modules/@angular/platform-browser/@angular/platform-browser.es5.js.DefaultDomRenderer2.appendChild (platform-browser.es5.js:2789)
    at DebugRenderer2.webpackJsonp../node_modules/@angular/core/@angular/core.es5.js.DebugRenderer2.appendChild (core.es5.js:13321)
    at createText (core.es5.js:11688)
    at createViewNodes (core.es5.js:12070)
    at callViewAction (core.es5.js:12530)
    at execComponentViewsAction (core.es5.js:12439)
    at createViewNodes (core.es5.js:12113)
    at createEmbeddedView (core.es5.js:11979)
    at callWithDebugContext (core.es5.js:13206)
    at Object.debugCreateEmbeddedView [as createEmbeddedView] (core.es5.js:12739)
    at DefaultDomRenderer2.webpackJsonp../node_modules/@angular/platform-browser/@angular/platform-browser.es5.js.DefaultDomRenderer2.appendChild (platform-browser.es5.js:2789)
    at DebugRenderer2.webpackJsonp../node_modules/@angular/core/@angular/core.es5.js.DebugRenderer2.appendChild (core.es5.js:13321)
    at createText (core.es5.js:11688)
    at createViewNodes (core.es5.js:12070)
    at callViewAction (core.es5.js:12530)
    at execComponentViewsAction (core.es5.js:12439)
    at createViewNodes (core.es5.js:12113)
    at createEmbeddedView (core.es5.js:11979)
    at callWithDebugContext (core.es5.js:13206)
    at Object.debugCreateEmbeddedView [as createEmbeddedView] (core.es5.js:12739)
    at resolvePromise (zone.js:769)
    at resolvePromise (zone.js:740)
    at zone.js:817
    at ZoneDelegate.webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)
    at Object.onInvokeTask (core.es5.js:4140)
    at ZoneDelegate.webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
    at Zone.webpackJsonp../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:191)
    at drainMicroTaskQueue (zone.js:584)
    at HTMLAnchorElement.ZoneTask.invoke (zone.js:490)

I don't want that each component write a new element. There is a way to avoid that?

like image 980
Pennywise83 Avatar asked Jun 08 '17 09:06

Pennywise83


People also ask

Can ngFor use NG-container?

Use ngFor and ngIf together using ng-container that means no styles or layout applied to it. We will refactor the above code using ng-container as shown below.

What is the difference between Ng content ng-container and ng-template?

ng-container serves as a container for elements which can also accept structural directives but is not rendered to the DOM, while ng-template allows you to create template content that is not rendered until you specifically (conditionally or directly) add it to the DOM.

Can we use nested ng-container?

You can also use as many <ng-container> elements as you like, and even nest them inside eachother for maximum composition and flexibility of your components.

What is the use of NG-container in Angular?

The <ng-container> allows us to use structural directives without any extra element, making sure that the only DOM changes being applied are those dictated by the directives themselves.


1 Answers

Reason

Yes, because the ng-container is a virtual element of DOM in Angular. With this element, you can add any conditions for render the DOM. As an example:

<ng-container *ngIf="1">
    <ng-container *ngIf="1">
        Element 1
    </ng-container>

    <ng-container *ngIf="0">
        Element2
    </ng-container>
</ng-container>

But, these elements are not really created DOM. The angular only creates the COMMENT_NODE for can next manipulate bindins. You can see this in next screenshot: Example for comments after ng-container

Conclusion

The comment node does not support add child nodes!

Solution

You should use the root attribute (as an example article) for adding you directive into the node.

<article product-cart product="product"></article>

But, in many cases, you must add the condition to render the element. This, you can use the ng-container for not render additional nodes in DOM.

<ng-container *ngIf="product.availableForPurchase">
    <article product-cart product="product"></article>
</ng-container>
like image 177
ZhukV Avatar answered Oct 21 '22 03:10

ZhukV