Override ember component template with template from addon (in-repo) - javascript

I want to create an in-repo addon to make certain modifications (styles, templates, etc.) to an existing ember app in an encapsulated way, but I'm having troubles overriding the templates.
Right now, I'm trying to override an existing component template with the template from a component with the same name in the in-repo addon. My code looks something like this:
// my-app/app/templates/components/foo.hbs
<h1>Some headline<h1>
// my-app/app/lib/my-addon/app/templates/components/foo.hbs
<h1>A different headline<h1> // -> this never shows up
I've tried a lot of switching around the template structure (like putting it in /addons or /app and linking to the template in different ways, but without success. My problem is that ember never uses the template from the addon.
If the component within the addon has a different name, like foobar.hbs, I can call it without a problem.
I'm currently looking through the source code and docs, trying to make sense of this. Is this even accomplishable the way I imagine it?
Thanks a lot!

You'd have to create the component in your ember app which, initially, will mean the component renders as nothing as it's a brand new, empty component. Then you'd dig into your node_modules, find the component file and template and copy over what you'd need to work with.
Here's an example. While working with ember-cli-jsonapi-pagination, I need to customize the paginate-collection component:
I created the component in my application.
I looked at the source: https://github.com/BookingSync/ember-cli-jsonapi-pagination/tree/master/app
In components/paginate-collection/component.js I copied over the component code, but you should be able to import it as well.
In components/paginate-collection/template.hbs I modified the template as needed.

Related

How to make component tags start with a prefix in Vue?

I am working on a project that I inherited from someone else, and I see a lot of <p-xxxx> tags, such as <p-page :has-something="val1" :has-another="val2" />, etc.(e.g. CompName -->
I'm looking around the directories and found a component called Page.vue that has such props in it: has-something and has-another. And structurally speaking, I'm sure the <p-page> corresponds to this component.
So how did this work? I checked the component's name field and it says Page.
EDIT:
I should also note that the component isn't registered at all. It's not imported either. I'm guessing it has something to do with
import '#/globals';
import '#/plugins';
in main.js, because I know we're using our proprietary UI component library. Can anyone point to where I can go read more about how this works? I thought I was pretty good at Vue, but apparently not good enough.
It depends on how the component is registered in the parent component, for instance, if the Page component is registered as:
components: {
PPage: Page
}
Then in the template, you'll refer to this component as <p-page ...
I figured it out.
In our proprietary library we're using, components were being exported out with p- as a prefix, and the library was injected into the whole app via vue.config.js, so there wasn't any importing in individual components.

In which lifecycle method should I place the materialize dropdown menu initializer in Vue js?

As you can see in the materialize docs, using this on a plain html file is quite simple: paste the html somewhere in the body, and paste the js initializer on a script tag. It works fine.
I'm wondering how I can use this on a vue component? I'm talking a .vue file with template, script, style sections.
You could try and call this code in one of Vue's lifecycle hooks (see this diagram to find out where exactly they're executed), you'll probably want to use mounted.
But keep in mind this isn't really a bulletproof solution. Vue may manipulate the DOM in different ways later and as such isn't necessarily compatible with Materialize. The best solution in these cases is always to find a framework-specific implementation of the components you're trying to use, e.g. Vue Material.
I would advice you to include initialize function to mounted() {...} section of a .vue single file component to make sure all HTML tags already exist.

Compile Component in Ember 2

I have a component in Ember2 that receives a parameter {{my-component product=p}}. I need to pre compile the component and get the generated html.
I have tried to use ember-cli-htmlbars-inline-precompile but without success. let template = hbs"{{mycomponent product=p }};
First its important to clarify the terms. Compiling a component does not mean to produce HTML! It basically means to produce a bytecode that can be used with the glimmer runtime to produce and update DOM. Ember will never produce HTML, and this is important to understand.
If you think ember produces HTML and then gives that to the browser to render you are wrong.
Ember directly produces DOM, and then keeps track of the DOM nodes to update the DOM and allow live binding.
So basically there is no public API in ember to do what you want.
Of course you can just render the component, and use this.element.outerHTML to access the HTML. But remember that with that you will lose all ember functionality like live-binding or actions.
This is especially tricky because google maps renders all into an iframe.
ember-wormhole shows that its possible to render ember content outside the main div, but they make use of private API and I think this possibility ends with the iframe.

Render dynamic templates in Ember.js

I am new to Ember, so this might be a stupid question, but bear with me. Is there a specific reason one can't render templates with a dynamic string? Specifically, I push various objects to a controller variable like this:
this.controllerFor('application').get('popups').pushObject({
resource: article,
template: 'article'
});
And then try to render them:
{{#each popup in model}}
{{ render popup.template popup.resource }}
{{/each}}
This doesn't work in Ember as-is, since it expects a string as the template. I just patched this in my ember source in the renderHelper function:
if(name.value) name = name.value();
This makes sure that if the name comes from a property, it gets converted to a string correctly. It works perfectly fine. What is the reason Ember doesn't support this out-of-the-box? Am I missing something?
A little background for the stuff above: I want to open lots of different resources in popups on the page, but I want to keep the popups separated from the rest of the current route so I can show them on their own page if needed without duplicating code. My idea was that I push all open popups to a global array, and they are rendered at the bottom of the page (A bit like we do it at the moment without ember). Maybe there is a better way to do this that I missed!
You want to
Create a popup template independent of route
Pass data to template and render it any where
Right ? If yes there is a very good concept of component in Ember.js
Component is a small module with is separate from application. It only depends upon the data passed into it.
It can be reused in different portion without ever effecting each other. They are especially good to run third party plugins like qtip etc.
here is good article about use case of component.

Ember.js: How do I associate my component with a model?

I am new to Ember.js and am trying to figure out how to piece things together at this point. One component I built, since I need a re-usable "widget" to use across many portions of my application, is a "site nav" widget. Basically, it's almost like the buttons/links you see in StackOverflow when you open a new question titled: "Questions Tags Users Badges Unanswered". In my app, these links have a name and id associated with them on the server-side. I want to be able to use this navigation widget on multiple parts of my app and it should be as simple as putting:
{{site-nav}}
into a template. I got that part working just fine, but the navigation is currently hard coded in handlebars. My question is, for a component, where is the right place to retrieve/populate model data from the server? For a controller, we do it directly from the controller's route definition. The component is not associated with a router. In fact, it can be re-used, as mentioned before, in several parts of the app.
I want to be able to drop this component into templates and have it populated with modeled nav from the server which has the name/IDs of the navigation I need. Where is the best place to do this? I'm guessing I'll still extend from something like DS.Model, but I'm not entirely sure where/when/how to integrate this with the component. When do I create the model and invoke a .find() type call to the server to populate site-nav with data?
you can pass value to component Passing properties to component
via handlebars.
{{my-nav navlist=listfromserver}}
so the list from server is in our controller can be passed to the component

Categories