Using ember linkTo from controller - ember.js

I have a fairly complex text that I need to generate programmatically for display within an ember template. So far I have put this text construction into a controller.
Unfortunately, the text also needs to contain hyperlinks to other pages within the same ember app. When I just insert a href links into the text, ember does not recognize those links and triggers a full page reload upon following the link.
Is there a way to invoke ember's linkTo helper from within a controller?
I could also try to put this into a template, but the logic is fairly complex and emblem is somewhat limiting in this regard.

You can use an action in the template and inside the action you can do this.transitionToRoute
http://emberjs.jsbin.com/uMeQAvuk/1/edit
BTW, the only reason it should be causing a full page refresh is if something is different in the base url (before the hash) than the current page, or if it is doing some sort of page refresh instead of just an anchor tag.

Related

Where is the equivalent hook of `didInsertElement` for template?

I am creating a "landing page" and there are some page logic (mainly animation and interaction) script need to be executed when the page is loaded.
I have tried to put script tag inside the template hbs directly but broccoli complains the syntax issues.
So I thought about the didInsertElement hook inside the component, however, there is no such hook for template.
Where can I put the JavaScript code for template without converting the existing part into component?
In Ember 2.x the only walkaround is to use Component.
You should check you syntax because I have tried this before and it works.
For my knowledge, I am not aware there is an equivalent hook inside route which is similar to didInsertElement.
You can also try partial helper inside the template and put your script inside another template to make is more clear.
{{foo}}
{{partial "nav"}}
You can read more about partial at,
http://emberjs.com/api/classes/Ember.Templates.helpers.html#method_partial
A similar question has been ask here,
https://discuss.emberjs.com/t/ember-2-0-2-10-trigger-script-after-ready/8948/2
and the suggestion is to use a component instead.

How to transition without changing the url in ember 1.11

I have a situation where the back button actually causes harm in my application and I seem to remember a solution in ember where I could have a single link-to helper not update the url (but keeping the routes /link-to helpers for other routes working as usual).
Is this still an option/possible in ember 1.11? If so - how? If no - what other options do I have if I need to prevent a single link-to from allowing the user to go back?
{{#link-to "foo.bar" bar}}details{{/link-to}}
Unfortunately the link-to helper doesn't pass the replace property down to the view itself, the LinkView does have a property replace which will replace the current route in history instead of just adding it to the history.
Option 1
Use an action instead of a link-to, and use this.replaceRoute/this.replaceWith instead of this.transition....
Option 2
Extend the LinkView and set replace: true, dupe the link-to helper code and call it link-to-replace and use your extended LinkView.

Cannot read property 'container' of null when using linkTo helper in an Ember template

I am creating an Ember application as an add-on to some HTML returned from the server. I need this HTML so that the site can be indexed by search engines, and also to speed up the initial page rendering for the users.
So my application consists of several Ember Views, appended to different DOM elements of the HTML generated by the server. I don't use master templates for routes, so I set renderTemplate function of each route to do nothing.
My Ember App is bound to body element and I can successfully append a custom view to an element down the tree. It works:
In this JSFiddle three last elements of the list are appended by Ember
But when I try to use linkTo helper in my template, I hit an error:
Uncaught TypeError: Cannot read property 'container' of null ember-latest.js:32224
which is in this function:
router: Ember.computed(function() {
return get(this, 'controller').container.lookup('router:main');
}),
In this JS fiddle I just add linkTo to the template, and it breaks everything
In general, can Ember work this way - having many Views scattered
over the HTML rendered by the server?
How can the example code be
fixed?
I've fixed your fiddle here, Check it out.
Seems like you are starter to Ember,
So here are some tips for you,
You should have an application template, which will be the root template and on which all the templates will be rendered.
You shouldn't access views using this.container.lookup, that is for debugging only.
You shouldn't append views to the DOM, it's the job of the framework to do.
By default your application will be appended to the body of the html, if you want it to be appended elsewhere, give the rootElement property when creating the application. Refer here for configuring your application.
The rootElement can be either a DOM element or a jQuery-compatible selector string. Note that views appended to the DOM outside the root element will not receive events. If you specify a custom root element, make sure you only append views inside it!
Don't access any controllers globally like App.itemsController.set("content", model), if you want to access another controller inside a route, use this.controllerFor, and to access inside another controller, use needs.
You need not create any controller instance like App.itemsController=Ember.ArrayController.extend({}).create();
The framework will take care of all these.
I found that I need to additionally bind the view and the container together to make this fiddle work
App.itemsView.set("controller", App.itemsController);
App.itemsController.set("container", this.container);
So the resulting working code snippet is here:
http://jsfiddle.net/ddegtyarev/6cBRx/6/
Again, let me reiterate that I'm building an hybrid Ember application - i.e. I have some HTML returned right from the server, and some appended by multiple Ember views in multiple places. This is why I have to manually create the views and bind them with controllers etc.

Different rendering techniques in emberjs handlebars template

I've been reading a lot on emberjs lately but something isn't really clear to me: I have a feeling that there are different ways of rendering a template. Can someone explain the differences between these:
{{render}}
{{partial}}
{{template}}
{{outlet}}
I'm using pre4, so if some of these keywords are obsolete, please notify.
You can search the Ember.JS source for all of these by searching for: Ember.Handlebars.registerHelper('?'. For example, to find the part where template is defined, search for: Ember.Handlebars.registerHelper('template'
{{template}}
Is similar to the {{partial}}, but looks for templates that you define in the Ember.TEMPLATES hash. From the source code we can see an example: Ember.TEMPLATES["my_cool_template"] = Ember.Handlebars.compile('<b>{{user}}</b>'); and then we can render it that way.
I heard a whisper that {{template}} is #deprecated, but I can't find where I found that information at the moment. However, it's worth mentioning that I've never found myself using this one. Instead I prefer {{partial}}.
Edit: It appears as though it isn't #deprecated as of
3df5ddfd4f. My mistake!
{{partial}}
This is different to the {{render}} approach in that the controller and view are inherited from the context that called it. For example, if you're in the UserRoute, and you load in a partial in your user template, then the UserView and UserController will both be passed to your partial, so they can access exactly the same information as its current parent.
Partial names, when defined, start with an underscore. For instance, a Profile partial will have the data-template-name of: data-template-name="_profile" but is inserted into your view as {{partial "profile"}}.
{{outlet}}
You'll probably find yourself using this one a lot. It's predominantly used in cases where the outlet changes frequently, based on user interactions. By transitioning to (this.transitionTo/{{#linkTo}}) another page, Ember inserts the view into the {{outlet}} and attaches the relevant controller and view.
As an example, if you're transitioning into /#/pets then, by default, Ember will load the PetsView into the {{outlet}}, and attach the PetsController, all of this after initialising the PetsRoute to take instructions before initialising the view and finding the controller.
{{render}}
This is a mixture of an {{outlet}} and a {{partial}}. It's used for static pages that don't switch out for other pages (as an outlet does), but it doesn't inherit the controller and view (as a partial does).
It's better with an example. Let's say you've got a navigation. Usually you'll only have one navigation, and it won't change for another one, but you want the navigation to have its own controller and view, and not to be inherited from the context (probably ApplicationRoute). Therefore when you insert the navigation ({{render "navigation"}}), Ember will attach App.NavigationController and App.NavigationView.
Summary
template: Consults a global hash and inserts the view when it finds it (possibly soon to be #deprecated);
partial: Used to split up complicated views, and inherits the controller/view from the parent (if you're in the UserController, then the partial will also have access to this, and its associated view).
outlet: Most widely used, and allows you to quickly switch out pages for other pages. Relevant controller/view attached.
render: Similar to an outlet, but is used for pages that are persistent across the entire application. Assumes the relevant controller/view, and doesn't inherit them.
Did I explain them well?
Just to clarify:
Partial: Inherited controller, inherited view, non-switchable;
Outlet: Relevant controller, relevant view, switchable;
Render: Relevant controller, relevant view, non-switchable;
The guide also provides some useful information here! Below is a quick summary:
I wanted to post another answer here that really helped me to clarify when to use the various template techniques -
Route
Using a route is when you need a full-blown route. A 'route' has a unique URL and consists of generated or user defined classes of the following type -
Route (Ember.Route)
Controller (Ember.Controller || Ember.ArrayController || Ember.ObjectController)
View (Ember.View)
Template (Handlebars template)
{{render}}
Use the {{render}} helper when you need a view but still need to provide some functionality with a controller. {{render}} does not have a unique URL and consists of the following -
Controller (Ember.Controller || Ember.ArrayController || Ember.ObjectController)
View (Ember.View)
Template (Handlebars template)
{{component}}
Use the {{component}} helper when you are building a commonly re-used template which exists independent of the context it is rendered within. An decent example may be if you were building a retail website and wanted to have a product view agnostic of where it is rendered. {{component}} does not have a unique URL nor a controller but instead has a component class and consists of the following -
Component (Ember.Component)
Template (Handlebars template)
{{partial}}
Use the {{partial}} helper when you are simply re-using some mark-up. {{partial}} does not have a unique URL nor any special backing like a component and consists of the following -
Template (Handlebars template)

EmberJs - How to update the Handlebars template content after the view load?

Is there any way in Ember to update the Handlebars template content and re-render the dependent views dynamically?
I tried by using Ember.TEMPLATES and Ember.Handlebars.compile method, but it didn't worked and the JSFiddle is available here, so any suggestions?
I don't know why you're attempting to do this, but if it's just for testing sake, here is a working fiddle http://jsfiddle.net/VTP4n/2/.
Ember caches the template inside the view as a computed property, so I'm overriding it and calling rerender on the view. I wouldn't even consider using this in production though.
Up until recently, it was as easy as overriding the template and then calling view.notifyPropertyChange('template'), but with the new container stuff, it's a lot more complex to do it cleanly.
Capture anything you want the user to manipulate in the template as a property of the view/controller and create a binding for it either as computed property or attach an observer to it. This way you can create a view dynamically and append it anywhere you want in your document.