Ember.js {{linkTo}} to itself does not render - ember.js

I have a problem with a linkTo that points to itself. The actual problem is in an application that has a sidebar with a set of links. The first time a click the link the model and view is loaded and displayed properly. However on the second click the view and/or model disappear.
I've condensed the problem in this jsfiddle. The index route displays a list of links and when clicking on one of the links it will display the detail. In the detail page I have a link to itself but when I click it the model does not show.
The detail template shows the content fine but note the {{firstName}} or {{lastName}}
<script type="text/x-handlebars" data-template-name="item">
<h2>Item Content:</h2>
{{#linkTo "item" id}}Reload me{{/linkTo}}
{{content}}
<ul>
<li>{{firstName}} {{lastName}}</li>
</ul>
</script>
I think the issue is similar to Ember.js - linkTo error on second call
Updated sample
Here is a new example With linkTo at the top levelwhere the {{linkTo}} item is in the top level application template
<script type="text/x-handlebars" data-template-name="application">
{{#linkTo "test" 0}}Test 0{{/linkTo}}
{{outlet}}
</script>
Following #intuitivepixel solution using an action gives me the same result
<script type="text/x-handlebars" data-template-name="application">
<a href="#" {{action reloadMe "test" 0}}>Test 0</a>
{{outlet}}
</script>

Not everything can be done with the {{linkTo}} helper, IMO for this kind of feature (like a reload) you should go for a {{action}} helper instead.
First define the action that does the routing for you when called:
App.TestRoute = Ember.Route.extend({
events: {
reloadMe: function(route, content) {
this.transitionTo(route, content);
}
},
serialize: function(model) {
return {id: model.id};
}
});
And then in your template:
<a href="#" {{action reloadMe "test" content}}>Reload me</a>
See here how you could implement it: http://jsfiddle.net/FSd6H/4/
Hope it helps.

Related

ember.js: conditional positioning of nested resource outlet

starting from the bloggr-client of the ember guide i would like to include the outlet of 'post' inside the 'posts' each loop, resulting in some kind of accordeon-like behaviour.
e.g., the router looks like this:
App.Router.map(function() {
this.resource('posts', function() {
this.resource('post', { path: ':post_id' });
});
});
the template (cleared of html tags for legibility) should do something like:
<script type="text/x-handlebars" id="posts">
{{#each model}}
{{#link-to 'post' this}}{{title}}{{/link-to}}
{{#if :post_id given and corresponding with this post}} <-- that's pseudo code ;-)
{{outlet}}
{{/if}}
{{/each}}
</script>
any idea how to accomplish this properly?
UPDATE 1:
to clarify, output on url '/posts' should be:
post 1 title
post 2 title
post 3 title
on url '/posts/1':
post 1 title
complete post 1
post 2 title
post 3 title
on url '/posts/2':
post 1 title
post 2 title
complete post 2
post 3 title
Basically, you want to be able to displays all of the posts on the posts route as an accordion? You're going about it wrong because you can only have one {{outlet}} per template. What you want to do is build a component, which would look something like this:
<script type="text/x-handlebars id="components/post-card">
{{#link-to 'post' post tagName="h2"}}{{post.title}}{{/link-to}}
<p>{{post.snippet}}</p>
</script>
And call it in the posts route like this:
<script type="text/x-handlebars" id="posts">
<ul>
{{#each}} -> if you're iterating through the model, no need to specify
<li>
<h3 {{action makeActive}}>{{title}}</h3>
{{#if active}}
{{post-card post=this}}
{{/if}}
</li>
{{/each}}
</ul>
</script>
You would add active as a property in your model, and makeActive would be an action in your controller that would make active true for the given model, and make the other ones false. This would model an accordion, though your route would not update.

inline / inplace editing for different form inputs in Ember

Views in the app we're developing are already written in Handlebars / Emblem and data is already taken from models.
I'm trying to figure out what's the best approach for inline / inplace in Ember. Problem: when nothing is clicked, the data is just a text. When you click the text depending on its type (date, plain text, list of items) the corresponding input field (date field, text field or select) is replaced and you can edit it.
Have you had experience with this issue? If so, please share your thoughts!
Here is one solution using an Ember.Component:
App.InlineEditComponent = Ember.Component.extend({
actions: {
toggleEditing: function() {
this.toggleProperty('isEditing');
}
}
});
With the template:
<script type="text/x-handlebars" id="components/inline-edit">
{{#if isEditing}}
<form {{action "toggleEditing" on="submit"}}>
{{yield}}
</form>
{{else}}
<span {{action "toggleEditing"}}>
{{value}}
</span>
{{/if}}
</script>
Usage:
<script type="text/x-handlebars" data-template-name="index">
{{#inline-edit value=someProperty}}
{{input value=someProperty type="date"}}
{{/inline-edit}}
</script>
Demo: http://emberjs.jsbin.com/OGEnOdA/2/edit
You can add more features (for example, end editing on focus-out the form element, etc.) but I think you get the basic idea.

Creating a Lightbox Route in Ember.js

My authentication system uses lightboxes, so that when a user clicks "Sign In" or "Sign Up", a lightbox pops up for them to input their credentials. The page they were on remains rendered behind the lightbox, and when they're done signing in, the lightbox disappears and the view returns to the way it was. I can get this to work when I deviate from the conventional Ember route flow by using a lot of Jquery, but I'd prefer to integrate this more tightly into the rest of my Ember app.
The problem is, the conventional Ember route flow expects views and templates to be handled in a particular way. Specifically, a route such as /sign-in will render the sign-in template within the application template, erasing whatever was there before. Since I want to preserve the view that was there before, this approach doesn't work.
Is there a way to tell an Ember view not to erase the current view, but instead to render an independent view such as a lightbox?
You can use named outlets and render a template into the outlet, in my aplication template I has an outlet called modal, and two actions in the ApplicationRoute, openModal and closeModal. The open one receives a template name and uses the route method render to set the outlet content, the close one renders an empty template.
App.ApplicationRoute = Ember.Route.extend({
actions: {
openModal: function(modal) {
this.render(modal, {into:'application', outlet: 'modal'});
},
closeModal: function() {
this.render('empty', {into: 'application', outlet: 'modal'});
},
}
});
Html handelbars
<script type="text/x-handlebars" data-template-name="application">
{{! Other application template code}}
<button {{action openModal 'hellow.modal'}}>Open it!</button>
{{outlet modal}}
</script>
<script type="text/x-handlebars" data-template-name="empty"></script>
<script type="text/x-handlebars" data-template-name="hellow/modal">
<div class="modal">
<div class="modal-header">
Hellow
</div>
<div class="modal-footer">
<button {{action closeModal}}>Close</button>
</div>
</div>
</script>
This is adapted from http://nerdyworm.com/blog/2013/04/20/ember-modal-example/

Porting a view hierarchy from ember-0.9.8.1 to ember-1.0.0-rc.6

I can not get my head around this. I have started from this jsfiddle (a showcase for image preview + upload), which is working with ember-0.9.8.1, and I am trying to get it working with ember-1.0.0-rc.6 in this jsbin.
This is the relevant part causing problems:
<script type="text/x-handlebars">
{{#view Ember.View contentBinding="App.myModel"}}
{{#view App.PreviewUploadImage name="logo_image" contentBinding="content"}}
{{view fileField}}
{{view previewImageView width="200" height="100" srcBinding="content.myModel_src"}}
{{/view}}
{{/view}}
</script>
Together with this js:
App.PreviewUploadImage = Ember.View.extend({
fileField: Ember.TextField.extend({...}),
});
As you can see in the console errors:
Assertion failed: Unable to find view at path 'fileField'
Assertion failed: You must pass a view to the #view helper, not fileField ()
Uncaught TypeError: Cannot read property 'proto' of undefined
But fileField is a Ember.TextField (so indeed a view) and is defined in the context where it is used (the view PreviewUploadImage).
So where is the problem then?
I guess the problem you are running into is due to the fact that the fileField view is not created automatically so the lookup fails.
Try to create the view instead of extending:
App.PreviewUploadImage = Ember.ContainerView.extend({
childViews: ['fileField'],
fileField: Ember.TextField.create({...}),
});
Update
edited my answer I forgot something substantial, to make the outer view a ContainerView and define fileField as a child view in the childViews array.
Hope it helps.
this does not reference the view, but your controller content. You will have to reference the view using view, like do this:
<script type="text/x-handlebars">
{{#view Ember.View contentBinding="App.myModel"}}
{{#view App.PreviewUploadImage name="logo_image" contentBinding="content"}}
{{view view.fileField}}
{{view view.previewImageView width="200" height="100" srcBinding="content.myModel_src"}}
{{/view}}
{{/view}}
</script>

following emberjs guide for #linkTo helper does not display individual post

I have a jsfiddle with a route as shown below, which is exactly thesame as the one in emberjs guides and when I click on the #linkTo helper attached to {{post.title}}, it ought to show me the individual post but it does not and instead the console shows this errors:
Uncaught Error: assertion failed: Cannot call get with 'id' on an undefined object.
Also when I click the posts link on the home page, it displays all the titles but in the console, it also shows this error:
Uncaught Error: Something you did caused a view to re-render after it rendered but before it was inserted into the DOM.
EmBlog.Router.map(function() {
this.resource("posts", function(){
this.route('show', {path: '/:post_id'}) ;
});
});
The template which is thesame as the emberjs guides
<script type="text/x-handlebars" data-template-name="posts/index">
{{#each post in content}}
<p>{{#linkTo 'posts.show' post}} {{post.title}} {{/linkTo}}</p>
{{/each}}
</script>
I looked at this commit that added support for string literals as param for {{linkTo}} and in particular the suggestions below from that commit:
Now, Ember allows you to specify string literals as arguments. {{#linkTo post popular}} would look up the "popular" property on the current context and generate a URL pointing to the model with that ID. While {#linkTo post "popular"}} would treat the string literal "popular" as the model.
It seems like the only issue was you forget to pass the context to the linkTo posts.edit helper in the posts/show template.
<script type="text/x-handlebars" data-template-name="posts/show">
<h1>Post</h1>
<p>Your content here.</p>
<h3> {{title}} </h3>
<h3> {{body}} </h3>
<br/>
<p> {{#linkTo 'posts.index'}} back {{/linkTo}}</p>
<p> {{#linkTo 'posts.edit' content}} Edit the post {{/linkTo}}</p>
</script>
Here is a working fiddle, BTW I've cleaned up a bit, some things seemed useless for me.
http://jsfiddle.net/rxWzu/9/