Angular template and transclusion: content out of order












1














I'm facing some challenges with Angular content projection.
I have a template that has some common HTML for every instance that will be used, and another part that will be subject to change from case to case, via transclusion (ng-content).
The problem is that no matter the order I use on my template DOM elements , the output is always the same.
Here's the code:



<ng-template #lol>
<ng-content select=".world"></ng-content>
<div>Hello</div>
</ng-template>

<ng-container [ngTemplateOutlet]="lol">
<div class="world">World</div>
</ng-container>


I would expect the produced result to be:



World
Hello


given that I'm placing first the transcluded element and only then the static part of the template. But even if I switch their order on the template, the result will always be:



Hello
World


And I can't understand why.
Can someone please shed some lights on why this is happening and what can I do to produce the output I want?
Thank you.



NOTE: Here's a StackBlitz with a full example: https://stackblitz.com/edit/angular-vfecbs?file=src%2Fapp%2Fapp.component.html










share|improve this question






















  • ng-content won't work in your case at all. You can even remove it and the result should be the same
    – yurzui
    Nov 20 '18 at 12:59












  • Why do you think that there is tranclution for embedded template? Where did you read that?
    – yurzui
    Nov 20 '18 at 13:06
















1














I'm facing some challenges with Angular content projection.
I have a template that has some common HTML for every instance that will be used, and another part that will be subject to change from case to case, via transclusion (ng-content).
The problem is that no matter the order I use on my template DOM elements , the output is always the same.
Here's the code:



<ng-template #lol>
<ng-content select=".world"></ng-content>
<div>Hello</div>
</ng-template>

<ng-container [ngTemplateOutlet]="lol">
<div class="world">World</div>
</ng-container>


I would expect the produced result to be:



World
Hello


given that I'm placing first the transcluded element and only then the static part of the template. But even if I switch their order on the template, the result will always be:



Hello
World


And I can't understand why.
Can someone please shed some lights on why this is happening and what can I do to produce the output I want?
Thank you.



NOTE: Here's a StackBlitz with a full example: https://stackblitz.com/edit/angular-vfecbs?file=src%2Fapp%2Fapp.component.html










share|improve this question






















  • ng-content won't work in your case at all. You can even remove it and the result should be the same
    – yurzui
    Nov 20 '18 at 12:59












  • Why do you think that there is tranclution for embedded template? Where did you read that?
    – yurzui
    Nov 20 '18 at 13:06














1












1








1







I'm facing some challenges with Angular content projection.
I have a template that has some common HTML for every instance that will be used, and another part that will be subject to change from case to case, via transclusion (ng-content).
The problem is that no matter the order I use on my template DOM elements , the output is always the same.
Here's the code:



<ng-template #lol>
<ng-content select=".world"></ng-content>
<div>Hello</div>
</ng-template>

<ng-container [ngTemplateOutlet]="lol">
<div class="world">World</div>
</ng-container>


I would expect the produced result to be:



World
Hello


given that I'm placing first the transcluded element and only then the static part of the template. But even if I switch their order on the template, the result will always be:



Hello
World


And I can't understand why.
Can someone please shed some lights on why this is happening and what can I do to produce the output I want?
Thank you.



NOTE: Here's a StackBlitz with a full example: https://stackblitz.com/edit/angular-vfecbs?file=src%2Fapp%2Fapp.component.html










share|improve this question













I'm facing some challenges with Angular content projection.
I have a template that has some common HTML for every instance that will be used, and another part that will be subject to change from case to case, via transclusion (ng-content).
The problem is that no matter the order I use on my template DOM elements , the output is always the same.
Here's the code:



<ng-template #lol>
<ng-content select=".world"></ng-content>
<div>Hello</div>
</ng-template>

<ng-container [ngTemplateOutlet]="lol">
<div class="world">World</div>
</ng-container>


I would expect the produced result to be:



World
Hello


given that I'm placing first the transcluded element and only then the static part of the template. But even if I switch their order on the template, the result will always be:



Hello
World


And I can't understand why.
Can someone please shed some lights on why this is happening and what can I do to produce the output I want?
Thank you.



NOTE: Here's a StackBlitz with a full example: https://stackblitz.com/edit/angular-vfecbs?file=src%2Fapp%2Fapp.component.html







angular transclusion ng-template angular2-ngcontent ng-content






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 20 '18 at 12:55









NunoM

126213




126213












  • ng-content won't work in your case at all. You can even remove it and the result should be the same
    – yurzui
    Nov 20 '18 at 12:59












  • Why do you think that there is tranclution for embedded template? Where did you read that?
    – yurzui
    Nov 20 '18 at 13:06


















  • ng-content won't work in your case at all. You can even remove it and the result should be the same
    – yurzui
    Nov 20 '18 at 12:59












  • Why do you think that there is tranclution for embedded template? Where did you read that?
    – yurzui
    Nov 20 '18 at 13:06
















ng-content won't work in your case at all. You can even remove it and the result should be the same
– yurzui
Nov 20 '18 at 12:59






ng-content won't work in your case at all. You can even remove it and the result should be the same
– yurzui
Nov 20 '18 at 12:59














Why do you think that there is tranclution for embedded template? Where did you read that?
– yurzui
Nov 20 '18 at 13:06




Why do you think that there is tranclution for embedded template? Where did you read that?
– yurzui
Nov 20 '18 at 13:06












3 Answers
3






active

oldest

votes


















0














You probably are not using it correctly. Suppose that you're using the template code that you've specified in the OP in a Component named HelloComponent.



It should then be used like this:



<app-hello>
<p class="world">Some projected Content</p>
</app-hello>


HEre's a Sample StackBlitz for your ref.






share|improve this answer





















  • Your StackBlitz is the same I shared (without any new changes), but I get your point. I know I can use an additional component for this, but I was trying to avoid that, and by chance, came across this (unexpected, for me) behavior.
    – NunoM
    Nov 20 '18 at 13:05










  • Well, the stackblitz does have an additional component named hello and I'm using it inside the AppCompoent to project some content. And the point of using ng-content is so that you could project some content into a Component from outside where you are using it.
    – SiddAjmera
    Nov 20 '18 at 13:09



















0














ng-content have special power where you place it, there it will replace the select content.



<ng-template #lol>
<ng-content select=".world"></ng-content> <--- World will be printed here
<div>Hello</div>
</ng-template>


Make sure where you add the ng-content there will be select content replaced. If you need Hello in up simply move the element first



<ng-template #lol>
<div>Hello</div>
<ng-content select=".world"></ng-content> <--- World will be printed
</ng-template>





share|improve this answer





















  • Could you please try that on the StackBlitz I provided? Even if I switch the order of the lines, the output is always the same: I'm trying to get "World Hello" and no matter the order of the lines, it always shows "Hello World"
    – NunoM
    Nov 20 '18 at 13:12





















0














Content projection is the concept of projecting a content from one component to another - if you are passing some value to you child component from parent component and the value changes dynamically then you can go for Content projection



In your case the whole <ng-template> gets passed to your <ng-container> thus it reads as Hello, World - there is nothing happening with the <ng-content> remove it you might find the same result



<ng-container [ngTemplateOutlet]="lol">
<div>Hello</div>
<div class="world">World</div>
</ng-container>


Your output will be like this when you inspect your code - thus only the <div>Hello</div> gets embedded inside your container - it doesn't pass any content form it to the <ng-template> - so that seems not a way to fix it



Try by passing the content from one component to another check this link



Hope it helps - happy coding :)






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53393478%2fangular-template-and-transclusion-content-out-of-order%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    You probably are not using it correctly. Suppose that you're using the template code that you've specified in the OP in a Component named HelloComponent.



    It should then be used like this:



    <app-hello>
    <p class="world">Some projected Content</p>
    </app-hello>


    HEre's a Sample StackBlitz for your ref.






    share|improve this answer





















    • Your StackBlitz is the same I shared (without any new changes), but I get your point. I know I can use an additional component for this, but I was trying to avoid that, and by chance, came across this (unexpected, for me) behavior.
      – NunoM
      Nov 20 '18 at 13:05










    • Well, the stackblitz does have an additional component named hello and I'm using it inside the AppCompoent to project some content. And the point of using ng-content is so that you could project some content into a Component from outside where you are using it.
      – SiddAjmera
      Nov 20 '18 at 13:09
















    0














    You probably are not using it correctly. Suppose that you're using the template code that you've specified in the OP in a Component named HelloComponent.



    It should then be used like this:



    <app-hello>
    <p class="world">Some projected Content</p>
    </app-hello>


    HEre's a Sample StackBlitz for your ref.






    share|improve this answer





















    • Your StackBlitz is the same I shared (without any new changes), but I get your point. I know I can use an additional component for this, but I was trying to avoid that, and by chance, came across this (unexpected, for me) behavior.
      – NunoM
      Nov 20 '18 at 13:05










    • Well, the stackblitz does have an additional component named hello and I'm using it inside the AppCompoent to project some content. And the point of using ng-content is so that you could project some content into a Component from outside where you are using it.
      – SiddAjmera
      Nov 20 '18 at 13:09














    0












    0








    0






    You probably are not using it correctly. Suppose that you're using the template code that you've specified in the OP in a Component named HelloComponent.



    It should then be used like this:



    <app-hello>
    <p class="world">Some projected Content</p>
    </app-hello>


    HEre's a Sample StackBlitz for your ref.






    share|improve this answer












    You probably are not using it correctly. Suppose that you're using the template code that you've specified in the OP in a Component named HelloComponent.



    It should then be used like this:



    <app-hello>
    <p class="world">Some projected Content</p>
    </app-hello>


    HEre's a Sample StackBlitz for your ref.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 20 '18 at 13:03









    SiddAjmera

    13.1k31137




    13.1k31137












    • Your StackBlitz is the same I shared (without any new changes), but I get your point. I know I can use an additional component for this, but I was trying to avoid that, and by chance, came across this (unexpected, for me) behavior.
      – NunoM
      Nov 20 '18 at 13:05










    • Well, the stackblitz does have an additional component named hello and I'm using it inside the AppCompoent to project some content. And the point of using ng-content is so that you could project some content into a Component from outside where you are using it.
      – SiddAjmera
      Nov 20 '18 at 13:09


















    • Your StackBlitz is the same I shared (without any new changes), but I get your point. I know I can use an additional component for this, but I was trying to avoid that, and by chance, came across this (unexpected, for me) behavior.
      – NunoM
      Nov 20 '18 at 13:05










    • Well, the stackblitz does have an additional component named hello and I'm using it inside the AppCompoent to project some content. And the point of using ng-content is so that you could project some content into a Component from outside where you are using it.
      – SiddAjmera
      Nov 20 '18 at 13:09
















    Your StackBlitz is the same I shared (without any new changes), but I get your point. I know I can use an additional component for this, but I was trying to avoid that, and by chance, came across this (unexpected, for me) behavior.
    – NunoM
    Nov 20 '18 at 13:05




    Your StackBlitz is the same I shared (without any new changes), but I get your point. I know I can use an additional component for this, but I was trying to avoid that, and by chance, came across this (unexpected, for me) behavior.
    – NunoM
    Nov 20 '18 at 13:05












    Well, the stackblitz does have an additional component named hello and I'm using it inside the AppCompoent to project some content. And the point of using ng-content is so that you could project some content into a Component from outside where you are using it.
    – SiddAjmera
    Nov 20 '18 at 13:09




    Well, the stackblitz does have an additional component named hello and I'm using it inside the AppCompoent to project some content. And the point of using ng-content is so that you could project some content into a Component from outside where you are using it.
    – SiddAjmera
    Nov 20 '18 at 13:09













    0














    ng-content have special power where you place it, there it will replace the select content.



    <ng-template #lol>
    <ng-content select=".world"></ng-content> <--- World will be printed here
    <div>Hello</div>
    </ng-template>


    Make sure where you add the ng-content there will be select content replaced. If you need Hello in up simply move the element first



    <ng-template #lol>
    <div>Hello</div>
    <ng-content select=".world"></ng-content> <--- World will be printed
    </ng-template>





    share|improve this answer





















    • Could you please try that on the StackBlitz I provided? Even if I switch the order of the lines, the output is always the same: I'm trying to get "World Hello" and no matter the order of the lines, it always shows "Hello World"
      – NunoM
      Nov 20 '18 at 13:12


















    0














    ng-content have special power where you place it, there it will replace the select content.



    <ng-template #lol>
    <ng-content select=".world"></ng-content> <--- World will be printed here
    <div>Hello</div>
    </ng-template>


    Make sure where you add the ng-content there will be select content replaced. If you need Hello in up simply move the element first



    <ng-template #lol>
    <div>Hello</div>
    <ng-content select=".world"></ng-content> <--- World will be printed
    </ng-template>





    share|improve this answer





















    • Could you please try that on the StackBlitz I provided? Even if I switch the order of the lines, the output is always the same: I'm trying to get "World Hello" and no matter the order of the lines, it always shows "Hello World"
      – NunoM
      Nov 20 '18 at 13:12
















    0












    0








    0






    ng-content have special power where you place it, there it will replace the select content.



    <ng-template #lol>
    <ng-content select=".world"></ng-content> <--- World will be printed here
    <div>Hello</div>
    </ng-template>


    Make sure where you add the ng-content there will be select content replaced. If you need Hello in up simply move the element first



    <ng-template #lol>
    <div>Hello</div>
    <ng-content select=".world"></ng-content> <--- World will be printed
    </ng-template>





    share|improve this answer












    ng-content have special power where you place it, there it will replace the select content.



    <ng-template #lol>
    <ng-content select=".world"></ng-content> <--- World will be printed here
    <div>Hello</div>
    </ng-template>


    Make sure where you add the ng-content there will be select content replaced. If you need Hello in up simply move the element first



    <ng-template #lol>
    <div>Hello</div>
    <ng-content select=".world"></ng-content> <--- World will be printed
    </ng-template>






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 20 '18 at 13:07









    Sheik Althaf

    26717




    26717












    • Could you please try that on the StackBlitz I provided? Even if I switch the order of the lines, the output is always the same: I'm trying to get "World Hello" and no matter the order of the lines, it always shows "Hello World"
      – NunoM
      Nov 20 '18 at 13:12




















    • Could you please try that on the StackBlitz I provided? Even if I switch the order of the lines, the output is always the same: I'm trying to get "World Hello" and no matter the order of the lines, it always shows "Hello World"
      – NunoM
      Nov 20 '18 at 13:12


















    Could you please try that on the StackBlitz I provided? Even if I switch the order of the lines, the output is always the same: I'm trying to get "World Hello" and no matter the order of the lines, it always shows "Hello World"
    – NunoM
    Nov 20 '18 at 13:12






    Could you please try that on the StackBlitz I provided? Even if I switch the order of the lines, the output is always the same: I'm trying to get "World Hello" and no matter the order of the lines, it always shows "Hello World"
    – NunoM
    Nov 20 '18 at 13:12













    0














    Content projection is the concept of projecting a content from one component to another - if you are passing some value to you child component from parent component and the value changes dynamically then you can go for Content projection



    In your case the whole <ng-template> gets passed to your <ng-container> thus it reads as Hello, World - there is nothing happening with the <ng-content> remove it you might find the same result



    <ng-container [ngTemplateOutlet]="lol">
    <div>Hello</div>
    <div class="world">World</div>
    </ng-container>


    Your output will be like this when you inspect your code - thus only the <div>Hello</div> gets embedded inside your container - it doesn't pass any content form it to the <ng-template> - so that seems not a way to fix it



    Try by passing the content from one component to another check this link



    Hope it helps - happy coding :)






    share|improve this answer


























      0














      Content projection is the concept of projecting a content from one component to another - if you are passing some value to you child component from parent component and the value changes dynamically then you can go for Content projection



      In your case the whole <ng-template> gets passed to your <ng-container> thus it reads as Hello, World - there is nothing happening with the <ng-content> remove it you might find the same result



      <ng-container [ngTemplateOutlet]="lol">
      <div>Hello</div>
      <div class="world">World</div>
      </ng-container>


      Your output will be like this when you inspect your code - thus only the <div>Hello</div> gets embedded inside your container - it doesn't pass any content form it to the <ng-template> - so that seems not a way to fix it



      Try by passing the content from one component to another check this link



      Hope it helps - happy coding :)






      share|improve this answer
























        0












        0








        0






        Content projection is the concept of projecting a content from one component to another - if you are passing some value to you child component from parent component and the value changes dynamically then you can go for Content projection



        In your case the whole <ng-template> gets passed to your <ng-container> thus it reads as Hello, World - there is nothing happening with the <ng-content> remove it you might find the same result



        <ng-container [ngTemplateOutlet]="lol">
        <div>Hello</div>
        <div class="world">World</div>
        </ng-container>


        Your output will be like this when you inspect your code - thus only the <div>Hello</div> gets embedded inside your container - it doesn't pass any content form it to the <ng-template> - so that seems not a way to fix it



        Try by passing the content from one component to another check this link



        Hope it helps - happy coding :)






        share|improve this answer












        Content projection is the concept of projecting a content from one component to another - if you are passing some value to you child component from parent component and the value changes dynamically then you can go for Content projection



        In your case the whole <ng-template> gets passed to your <ng-container> thus it reads as Hello, World - there is nothing happening with the <ng-content> remove it you might find the same result



        <ng-container [ngTemplateOutlet]="lol">
        <div>Hello</div>
        <div class="world">World</div>
        </ng-container>


        Your output will be like this when you inspect your code - thus only the <div>Hello</div> gets embedded inside your container - it doesn't pass any content form it to the <ng-template> - so that seems not a way to fix it



        Try by passing the content from one component to another check this link



        Hope it helps - happy coding :)







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 '18 at 13:22









        Rahul

        1,0231315




        1,0231315






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53393478%2fangular-template-and-transclusion-content-out-of-order%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Paul Cézanne

            UIScrollView CustomStickyHeader Resize height generates problems when scroll is too fast

            Angular material date-picker (MatDatepicker) auto completes the date on focus out