How to inject components in whole application in ember.js - ember.js

I'm on developing a ember-cli project where I have created many reusable components. I want these components in every template(hbs) file. I can do {{component1}} {{component2}} {{component3}} in each template but this looks redundant to me since I've to write all these lines in every template. All I want to know is if I can inject components in all the templates like way services are injected into routes, components etc where ever I need.
Example of how I inject services is below
/intializers/session-object.js
export function intialize (application){
application.inject('route','session','service:session');
application.inject('controller','session','service:session');
application.inject('component','session','service:session');
application.inject('adapter','session','service:session');
});
I tried injecting the components into templates as similar as above.
/intializers/session-object.js
export function intialize (application){
application.inject('template','my-component','component:my-component');
});
As expected, the above code fails. No where in the ember guides is mentioned that I can inject components in templates. But, wanted to know if anybody did this before.
I believe there could be a strong reason why ember is not allowing us to inject components into templates.
Any help in explaining the reason why this cannot be implemented in ember.js is great or providing a solution if it can be implemented is awesome. Thanks in advance guys.

Injecting to template is not meaningful.
You can create a partial template and put that common components there then use that partial.
-common.hbs
{{nav-bar}}
{{error-messages}}
another.hbs
{{partial 'path-to-common-template'}}

Related

Ember JS automatically register directory classes to DI

Creating in-repo-addon in Ember.JS gives a lot of possibilities. Today I've stumbled into a case when I wanted to register all classes in directory (for example my-dir) into Dependency Injector (same way it's done with services by Ember, but I wanted to use some other namespace).
For example I want to allow developer to create multiple classes inside proxy directory, and register all of them in DI under proxy: namespace. So later we can use:
Ember.Component.extend({
myProxy: Ember.inject('proxy:my'),
});
You'll need to do this using an initializer. More details on this here: https://guides.emberjs.com/v2.12.0/applications/dependency-injection/
The hard part may be getting all proxy items in s folder to automatically register ...
Edit
Looks like I didn't spend enough time thinking about this. You should be able to do at least part of this easily. There are two parts to this.
Part 1
Ember currently uses the ember-resolver to handle lookups for various items. If you check the tests for the resolver you'll notice that you should be able to map in anything you want: https://github.com/ember-cli/ember-resolver/blob/master/tests/unit/resolvers/classic/basic-test.js
So in your case, if you do a Ember.getOwner(this).lookup('proxy:main') from within an Ember instantiated class (a route, controller or component for instance) it would look in app/proxy/main.js which your addon could be populating.
Details on the Ember.getOwner lookup are available here: https://emberjs.com/api/classes/Ember.html#method_getOwner
Part 2
So at this point you can lookup proxies (which would be doable in an init method). But if we want to get truly elegant we'd want to allow Ember.inject.proxy('main') syntax.
Doing so would involve calling a private method inside of Ember.inject in an initializer. Because that naming scheme is changing in the new Javascript modules RFC, it may be unwise to try to add this syntactic sugar ...
So I'd advise avoiding touching that private API unless it's really important to your app design.

How to render component/helper from another one?

I have render-component ( source ) which used to render components/helpers from controller fields. It worked fine for ember 1.9.1 but after updating up to ember 1.12.1 I found changes in API. After updating code I restore simple cases ( like render view by name from some property ). But largest part of functionality still broken.
I'm interesting about where can I read more about such things like
env ( which used inside components/helpers internal implementation )
morph ( I understand that it's a part of html-bars, but I'm interested in more documentation )
hooks ?
Can anyone share some experience at creating such helper ? Or way to find solution in such cases? ( I mean that this things not fully documented )
P.S. I know about component-helper from ember 1.11 -- but it doesn't allow render helpers ( with params) and using it I should define all properties in template. And when name of component/helper is dynamic -- I should pass different params / attributes.
Thx in advance
P.P.S
Some examples of functionality I want restore with my helper ( more examples and motivation you can find at helper page -- I just want note difference between my helper and build-in component-helper ):
{{#render-component componentName _param='btn-component' action="addSection"}}
{{render-component 'pluralize-component' ___params=hash}} // hash = { count:ungrouped.content.meta.total, single:"Object"}
{{#render-component 'componentName' _param=paramName someOption=someOptionValue}}
You've got quite a few questions here, but to answer the one in your title: Ember 1.11 introduced the component helper that allows you to dynamically render components.
componentName: 'someComponentName'
...
{{component componentName param=value someAction='someMapping'}}
This article contains most of the information one might use to implement what I think you're getting after (compared to the standard component helper).
One notable out-of-the-box solution they suggest is the use of the (almost deprecated) dynamic-component addon.
{{dynamic-component
type=theType
boundProperty=foo
staticProperty="bar"
onFoo="fooTriggered"
}}
Hopefully this (and other suggestions from the article) steer you towards your solution.
I was looking for an answer to this, ended up with a solution myself.
My scenario was that I wanted to pass in a component to another component and render it inside that component, which sounds like what this question was aiming for.
For those who don't clearly know how the {{component}} helper works:
Use it to render another component.
{{component "component-name" param1="value" param2="value"}}
This would work exactly the same way as:
{{component-name param1="value" param2="value"}}
For my scenario, I did this:
In the template invoking the first component:
{{my-comp-1 comp=(component "my-comp-2" param1="value" param2="value") other-param="value"}}
In my-comp-1's template, use the attribute used for the component:
{{component comp}}
That was all I needed to do.
This works perfectly as of Ember 2.7.0.

ember app kit: some testing functions not defined

Building my first ember app based on ember app kit.
I wanted to test the current route after transition - and found just what I need in ember docs - currentRouteName, currentURL and currentPath helper functions.
However, if I use these functions i get a "ReferencError: currentRouteName is not defined".
I stumbled upon this pull request that I suppose has the initial implementation of the same thing - but was closed in favor of adding this functionality to ember proper... For the time being, I copied the code from this PR and it does indeed get picked up and pass my tests.
Question: how can I utilize all the functions defined in my copy of ember.js in testing?
These route helper functions are defined alongside with visit and click functions, which my tests seem to pick up without issue. Or, are my tests picking these functions up from somewhere else?
Those methods weren't added as global helpers until 1.5, so they are only available in the canary builds as of writing this.
http://emberjs.jsbin.com/wipo/2/edit

Lazy Loaded Ember Application

I am typically searching for answers here but I finlly gotten to the point where I can't find a good answer.
I am looking to build an ember app which only initially loads in the things that it needs just to start and open the main route. All other controllers, views, templates, etc. Would be loaded lazily when a specific route gets triggered.
I have found a good example of how to accomplIsh this here:
http://madhatted.com/2013/6/29/lazy-loading-with-ember
My main question is to determine what build tools out there support this theory of lazy loading application code? So far, I've seen that Brunch, Yeoman, and Ember App Kit seemed to minify and concatenate all the scripts and templates. I am very happy with minification but need those files separate. I have thought about just putting this code into the app/assets location so that it gets copied over without concat but it does not get minified.
Does anyone have a solution? Thanks!
You can do this with brunch by adding the following to your brunch config
files: {
javascripts: {
joinTo: {
'javascripts/app.js': /^app(\/|\\)(?!admin)/, // concat everything in app, except /app/admin
'javascripts/vendor.js': /^vendor/,
'javascripts/admin.js': /^app(\/|\\)admin/ // concat only /app/admin
}
}
}
Grunt (used in yeoman and ember app kit) is ridiculously flexible, so I'm sure you can set up the same thing there by diving into Gruntfile.js
The question was: "I am looking to build an ember app which only initially loads in the things that it needs just to start and open the main route. All other controllers, views, templates, etc. Would be loaded lazily when a specific route gets triggered.".
Ember expects to have anything it needs right there when the page gets loaded. I wouldn't be wrong, but lazy loading of routes doesn't seem to be a feature of Ember. Ember CLI is the same. It uses bundling and minification to reduce the overload. But everything should be there to make it work.
Instead, people like me would like to load things only when they are required.
When you try to implement lazy loading in Ember, everything should be represented by a module (file.js): a route, a module; a controller, a module; and so on.
You should follow a schema (like POD), to which apply a mechanism to find things where they are supposed to be.
Every module should know its dependencies. But some of them are very frequent (route, controller, template).
You should use a module loader for the browser. It can be requirejs or whatever you like. But ES6 is at the door. Let's think about that.
Many people use beforeModel hook to achieve a result. I did it, and it works, if you don't use link-to component. Otherwise everything crashes. Why? Because of href computed property. When a link-to has been inserted, an href is calculated for it. Because of that, Ember looks for the route where the link points to. If the route doesn't exist, one is created from route:basic.
A solution could be the preloading of all the routes represented by all link-tos inserted in the page. Too much expensive!
An integration to this answer can be found at Lazy loading route definitions in Ember.js
For an initial solution to lazy loading of routes organized in POD, have a look at https://github.com/ricottatosta/ember-wiz. It is an ES6 based approach, which relay on SystemJS as module loader.

Emberjs Templating from file?

How I can do to get the template Handlebars from file, like this:
App.ApplicationView = Ember.View.extend({templateName: 'templates/myTemplate1.handlebars'});
not from script:
< script type="text/x-handlebars" data-template-name="myTemplate1">
Update
I Will implement Ember-Brunch handlebars template pre-compiling
If you intend on assembling your finished application you can use something like rake-pipeline. This, of course, implies that you also need to use rake-pipeline during development.
If you do not want to assemble your templates, you can call Ember.TEMPLATES['templateName'] = Ember.Handlebars.compile('template content goes here') in your app. You can then separate these templates out to different files, which you will include in your index.html file.
Other than that I do not think there are other options. You could fetch your templates via an AJAX call and feed them into Ember.Handlebars.compile, but then you risk your templates being available too late in the application's lifecycle. Another option is to generate this on-the-fly on the server that delivers your Ember app, but you then most likely have to build-your-own solution.
Refer to the following for an application that uses the Ember.TEMPLATES[''] option: https://github.com/joachimhs/haagen-software.no/tree/master/app/
It is a little cumbersome, but you do get used to it...
There really isn't that many great options for this sort of functionality, and its not a whole lot Ember.js can do about it I'm afraid. .
I believe requirejs + require-handlebars-plugin does exactly what you need. You will have to convert your js application to use requirejs though, but that shouldn't be hard.
More info about requirejs: http://requirejs.org/
require-handlebars-plugin: https://github.com/SlexAxton/require-handlebars-plugin