Consider that I am getting a component from a api response or a component passed via args.
Example
let myButton = "<CustomButton class='btn'>Clickme</CustomButton>";
(or)
<SomeComponent @anothercomponent={{<OtherComponent />}} />
How can i get the actual HTML of these component and render it ?
do you mean the name of a component? or actual html/template code?
let myButton = "<CustomButton class='btn'>Clickme</CustomButton>";
^ To render something like this you’d need to compile the templates at runtime. I’d look at @NullVoxPopuli 's ember-repl/limber project for ideas.
<SomeComponent @anothercomponent={{<OtherComponent />}} />
^ This sort of thing is already possible though not quite like you have written it here. Depending on what version of Ember you’re using and if you have gjs/gts components set up you can do various things:
// classic resolved components, "loose mode"
<SomeComponent @anothercomponent={{component "other-component" foo=bar}} />
This would pass “OtherComponent” into “SomeComponent” as a “CurriedComponentInstance” with one bound component arg, @foo
. Inside “SomeComponent” you could then render OtherComponent in a few ways:
// some-component.hbs
...
{{!-- remember we've already bound @foo arg too --}}
<@anothercomponent @somearg={{somevalue}} />
or
// some-component.hbs
...
{{!-- remember we've already bound @foo arg too --}}
{{#let @anothercomponent as |AnotherComponent|}}
<AnotherComponent @somearg={{somevalue}} />
{{/let}}
If you’re using gjs/gts “Strict mode templates” you can get a little crazier:
// components/my-fancy-component.gjs
import SomeComponent from '...';
// this is a private child component
const PrivateChildComponent = <template>
<button {{on "click" @onClick}}>Do Stuff</button>
</template>;
// this is the main component we actually export from the file
export default class MyFancyComponent extends Component {
doFancyStuff = () => {
// do some fancy stuff when the button is clicked
};
<template>
<SomeComponent />
...
{{#if (has-block "actionZone")}}
{{yield (component PrivateChildComponent onClick=this.doFancyStuff)}}
{{else}}
<PrivateChildComponent @onClick={{this.doFancyStuff}} />
{{/if}}
</template>
}
Hope that helps a little bit. Feel free to dig in more if you’re going for something different.
@dknutsen Thanks for your response.
I’m already using this component helper to pass the component in props
<SomeComponent @anothercomponent={{component "other-component" foo=bar}} />
But it is not that much helpful consider that I want to pass a block component, And i can’t provide any event handler and html attributes (class, id, name, etc) to this anothercomponent.
I guess the ember-template-imports solves this problem But It will be better if we have some thing built-in by default.
And my use case is that I am getting the api response from the server in json which has components in it.
{
status:200,
message: 'In Progress <LinkTo @to="status"> Click here to view the progress.
<Icon @name="icon-right" /></LinkTo>.',
}
So is there any way to handle this message and listen events if any.