Comments (13)
@narendrapandey999 I had a look into your plunkr.
First of all there were some errors not related at all to my library (some angular-cdk errors) that I had to fix.
Finally I upgraded my library from v1.1.0 (which is quite outdated) to v3.1.1 and took advantage of (ndcDynamicCreated)
output that allowed me to get a reference to created component and then execute it's method.
One important thing to note is that when (ndcDynamicCreated)
output emits outputs are not yet bound to your component so you should wait one JS tick to then trigger your emit (via setTimeout
).
Here's the fixed version: https://stackblitz.com/edit/angular-with-ng-dynamic-component-k4olqc?file=app%2Fspawner.component.ts
EDIT: I also added content projection, and in your spawner component I grab it like this <div #content><ng-content></ng-content></div>
and then I can pass content via content
to [ndcDynamicContent]="[[content]]"
Be aware that the div
element will also go inside with projected content. It is required to have in order to properly get the reference to it.
from ng-dynamic-component.
We to pass the content you need to specify where that content will go in the component (in your case in comp-trial
and in dyn-comp1
).
You can do that by placing <ng-content></ng-content>
.
This technique is called Content Projection.
But since you have to pass that content from your comp-trial
you can try to create a local template variable on that content, and then forward it to dynamic component:
comp-trial:
<!-- Make sure this piece is hidden from user -->
<ng-content #content></ng-content>
<ndc-dynamic
[ndcDynamicComponent]="dynamicComponent"
[ndcDynamicInputs]="inputs"
[ndcDynamicOutputs]="outputs"
[ndcDynamicInputs]="[[content]]"
>
</ndc-dynamic>
dyn-comp1:
<div>{{ title }}</div>
<div class="content"><ng-content></ng-content></div>
And btw, your types in TrialComponent
of inputs and outputs properties are incorrect, instead of Array<any>
they should be objects ({[key: string]: any}
).
Cheers.
from ng-dynamic-component.
Thanks for a quick reply !
Nice trick to create the local variable on content. My content does appear in the added not-yet-hidden ng-content node of the Trial component (comp-trial).
However, adapting my code that way (and considering you meant to write:
[ndcDynamicContent]="[[content]]"
), I get the following error:
TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
It seems to be 'undefined': ideas?
from ng-dynamic-component.
I suspect that the local variable might be of type TemplateRef
. In that case you can try to access property nativeElement
to pass into ndcDynamicContent
.
Also in comp-trial
you can try to query-select ng-content
by that local template variable name and console log it on AfterContentInit
hook to see exactly what you get.
This was always tricky part to forward real content that way and I never saw an example in official Angular docs how to do it although they have exactly the same support on NgComponentOutlet
directive...
from ng-dynamic-component.
Ok, so after trying few things, it seems that a ng-content
node is not a valid node to pass to ndcDynamicContent
. So I wrapped it in another proper node, and it works fine now.
My working code, for the archives:
Trial Component
@Component({
selector: 'comp-trial',
template: '
<div style="display:none">
<span #mycontent>
<ng-content></ng-content>
</span>
</div>
<ndc-dynamic
[ndcDynamicComponent]="dynamicComponent"
[ndcDynamicInputs]="inputs"
[ndcDynamicOutputs]="outputs"
[ndcDynamicContent]="[[mycontent]]"
>
</ndc-dynamic>
'
})
export class TrialComponent {
dynamicComponent; // the component to insert dynamically (management of this var is not developed here)
@Input() inputs: Array<any>;
@Input() outputs: Array<any>;
}
One of the dynamic component
@Component({
selector: 'dyn-comp1',
template: '
<div>{{ title }}</div>
<div class="content"> <ng-content></ng-content> </div>
'
})
export class ExpandablePanel1Component extends ExpandablePanel {
@Input() title;
@Output() click;
}
Using the trial component
...
<comp-trial
[inputs]="{ title:'...' }"
[outputs]="{ click: myOnClickHandler }"
>
This is some content for the dynamic components
</comp-trial>
...
Thanks for the help, and the library !
from ng-dynamic-component.
Great!
Thanks for sharing the solution, very helpful 👍
from ng-dynamic-component.
Hello,
In my case Trial Component (dummy-spawner) is being called from another component and in their I am setting data like below -
<dummy-gridster-item [item]="{cols: 1, rows: 1, y: 0, x: 5}">
<dummy-spawner [input_component]= "component" [received_input_data]= "input" (output_data)='changereceived($event)' fxFlex="30%">
<dummy-header #CardHeader>
<dummy-title>{{header}}</dummy-title>
</dummy-header>
<dummy-content>
<section fxLayout="column" fxLayoutAlign="center center">
<dummy-metric dummyMetricScale="xxl" align="center">
{{content}}
<dummy-metric-detail>users</dummy-metric-detail>
</dummy-metric>
</section>
</dummy-content>
<dummy-footer fxLayoutAlign="start" >
{{footer}}
</dummy-footer>
</dummy-spawner>
</dummy-gridster-item>
Here dummy-spawner is Trial component. Below is my dynamic component -
<mat-card >
<mat-card-header >
<ng-content select="dummy-header"></ng-content>
</mat-card-header>
<mat-card-content>
<ng-content select="dummy-content"></ng-content>
</mat-card-content>
<mat-card-footer>
<ng-content select="dummy-footer"></ng-content>
</mat-card-footer>
</mat-card>
So i am have received value from dynamic component emit event and have saved them in header, footer and content of dummy-gridster-item component. I am trying to add these values directly using "{{header}}". But it doesn't work.
I have used above approach and added the class manually in above ndc-dynamic imports. But i am trying to avoid that. Is there any other way so that I could maintain the styling as well making less changes caller component(dummy-gridster-item component)
from ng-dynamic-component.
Please provide live example of your problem on stackblitz.com then I might have a look.
from ng-dynamic-component.
Hello Gund, Below is the stackblitz url.
https://stackblitz.com/edit/angular-with-ng-dynamic-component-c6vexd
It is currently having some import issue hence not working correctly.
In it, I am passing data from my app component to a spawner component. Spawner component spawn the component received and call its HelloTwComponent.execute() method. It emits back data to output() method of spawner component and then again spawner component emits back to app component changereceived() method.
I am trying to use this received data and component to set data in app.component.html => Card-header.
Cad-header content is input to HelloTwoComponent. I am trying to inject value for HelloTwoComponent through appComponent's html. As HelloTwoComponent have more component embedded to it and expects ng-content input of those components, i am following such approach.
from ng-dynamic-component.
Hello @gund, thanks for the working code.
I am still facing issue with spawning as the rendered data from child component is being set in my code but it still doesn't get spawned in web page. Could there be a possible object initialisation issue as my app_component have a ngAfterViewChecked() call (I have to add this check to get recent modifications from child component) and ndcDynamicCreated.instacne.execute() gets called quite later.
In my code, i was calling execute() function of child through OnInit() block. I have replaced that part with ndcDynamicCreated.instacne.execute() and have removed that code from OnInit call.
To debug this issue, i tried adding hard coded value in n app_component.html.
<card-title>123</card-title>
It surely gets reflected in plunkr but not in actual code. any thoughts what else could be missing
from ng-dynamic-component.
Also, is it mandate to use ndcDynamicCreated or if we can invoke the underlying method of child component through other means. For eg, making part of ngOnInit()
from ng-dynamic-component.
Ok. After lot of hit n trial , it worked. I was missing <div>
tag in my projected content (as you have mentioned in :( ). So i enclosed my child component html with <div>
tag and it worked. It didn't took the styling as required , but it seems specific to our project. Thanks again :)
from ng-dynamic-component.
Hello @gund , I am using below code in my spawner template -
div #content><ng-content></ng-content></div>
<ndc-dynamic [ndcDynamicComponent]="component"
[ndcDynamicInputs]="dynamicInput"
[ndcDynamicOutputs]="dynamicOutput"
[ndcDynamicContent]="[[content]]"
(ndcDynamicCreated)="componentCreated($event)"
></ndc-dynamic>
Consider, i am using this template to pass a dynamic component. But the values are not getting set at correct position in dynamic component template. Values are simply getting entered in above the actual template. They are positioned as per I have placed div #content><ng-content></ng-content></div>
. If it is before <ndc-dynamic>
block, it adds all data above my template and if its below <ndc-dynamic>
block then data is placed below my dynamic template.
For eg - if div tag is paced ahead
{{header}}
{{content}}
{{footer}}
<mat-card >
<mat-card-header >
<ng-content select="dummy-header"></ng-content>
</mat-card-header>
<mat-card-content>
<ng-content select="dummy-content"></ng-content>
</mat-card-content>
<mat-card-footer>
<ng-content select="dummy-footer"></ng-content>
</mat-card-footer>
</mat-card>
Can't we really add data from spawner component to dynamic component in my above example? Is there some sort of restriction??
from ng-dynamic-component.
Related Issues (20)
- Is this project abandoned? HOT 3
- Question about dynamic templates HOT 2
- Support RxJS ^7.4.0 HOT 2
- Support for Angular 14 HOT 7
- Need add rxjs 7 support for version 9.x.x HOT 14
- Building app with angular 13 leads to compile error HOT 6
- Outputs initialized after inputs which leads to missed events triggered synchronously from constructors/setters HOT 2
- Cannot access 'IoService' before initialization HOT 8
- Backwards compatibility with Angular 13 in minor update v10.x.x is broken HOT 1
- [Question] How to call functions mentioned in dynamic components HOT 2
- Support for Angular 15 HOT 4
- Ability to provide ngModuleRef when creating component HOT 4
- [BUG] `IoEventContextToken` is not exported HOT 3
- Unknown input error after updating from no-barrels version [Bug] HOT 1
- Property 'withComponents' does not exist on type 'typeof DynamicModule'. HOT 1
- Support angular 14 HOT 1
- Component not support nested HOT 2
- [Bug] HOT 2
- Support for Angular 16 HOT 3
- Angular 17 support HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ng-dynamic-component.