I require another controller in the application controller:
App.ApplicationController = Ember.Controller.extend({
needs: ['login'],
...
Then I try to use some of the properties of the login controller in the application template:
{{#if controllers.login.token}}
<li>
<a {{action logout}} href="#/">log out</a>
</li>
{{else}}
<li>
log in
</li>
{{/if}}
When I write {{log controllers.login.token}} directly over the #if I get null.
But the if branch is still shown, not the else branch.
null is falsey. Example: http://emberjs.jsbin.com/jivoqa/1/edit
{{log xyz}} is deceptive, it logs it when the page is being built, not necessarily what the value still is. You'd be better off doing {{xyz}} and just tossing it in the page to see what it is.
Related
I have an odd conundrum.
It appears that when an element is hidden by a focus-out event ember is unable to attach the corresponding click event that triggered the focus out properly. For example with the code below if the <a> tag triggers the focus-out event on the input and the code behind turns _focused to false then the selectOpts event is never triggered. It appears to only happen if the a tag is hidden as a result of the focus-out.
Also oddly it does not matter how the a tag is hidden either if i do just display:none it still also doesn't fire the selectOpt action.
Here is my code:
<div class="dropdown">
{{input value=value class='form-control' focus-in="focused" focus-out="unfocused" }}
{{#if _focused}}
<ul class='dropdown-menu'>
{{#each _filteredOptions as |opt|}}
<li><a href="#" {{action "selectOpt" opt}}>{{opt}}</a></li>
{{/each}}
</ul>
{{/if}}
</div>
Here is a ember twilldle showing the issue.
https://ember-twiddle.com/6bbdb669d19d7a498e645bb0297f1b46?openFiles=templates.components.input-autocomplete.hbs%2Ctemplates.components.input-autocomplete.hbs
In order to get it to show the issue focus in on the text area and then try to select one of the links that appear below the input. What is supposed to happen is that when you select the link it is to populate the input field with the value.
You can use just focus-in instead of both focus-in and focus-out. So when you click on input focus-in event trigger and set _focused to true. Then, in action selectOpt you set value and after that set property _focused to false.
<div class="dropdown">
{{input value=value class='form-control' focus-in='focused' }}
{{#if _focused}}
<ul class='dropdown-menu'>
{{#each options as |opt|}}
<li>
<a href="#" {{action "selectOpt" opt}}>{{opt}}</a>
</li>
{{/each}}
</ul>
{{/if}}
input-autocomplete.js
actions: {
focused() {
this.set('_focused', true);
},
selectOpt(opt) {
console.log(opt);
this.set('value', opt);
this.set('_focused', false);
}
}
I didn't include all code for input-autocomplete it's the same as before exxept actions. Also I used options array insted your filter because didn't get any results when clicked on input.
I have an app setup using ember-cli 0.1.1 and I'm using ember-simple-auth (along with devise cli plugin) for login. In my application template, I have a menu with a conditional wrapped around it:
{{#if session.isAuthenticated }}
<div class="nav_user">
<p>{{session.user_name}}</p>
<p class="user_account">{{#link-to 'account-settings'}}<img src="assets/images/gear.png" />{{/link-to}}</p>
</div>
<ul>
<li>{{#link-to 'horses'}}My Horses{{/link-to}}</li>
<li>{{#link-to 'veterinarians'}}Veterinarians{{/link-to}}</li>
<li>{{#link-to 'documents'}}Documents{{/link-to}}</li>
<li>{{#link-to 'notes'}}Notes{{/link-to}}</li>
</ul>
<ul>
<li><a {{action 'invalidateSession'}}>Logout</a></li>
</ul>
{{/if}}
The problem is that after a successful login, I transition to another route and if I immediately open the menu, the non-authenticated menu is what appears. If I refresh, then I get the correct menu contents. I'm looking for a way to updat session.isAuthenticated after a successful login, prior to transitioning to the new route. Thanks in advance for any help.
I was following the tutorial but the tutorial is for the object controller. In an Array controller how do I properly pass in the object for the text field so it triggers the update for that model object?
Right now I can double click, and then type in some value, and if I hit enter I get the value plus undefined method set.
Uncaught TypeError: Object asdasdasdasdasd has no method 'set'
I guess it's passing the raw value into the controller and then trying to run methods off of that. How do I get it to pass the actual model?
View:
<ul>
{{#each}}
<li {{bind-attr class="isEditing:editing"}} {{action "editWorkout" this on="doubleClick"}}>
{{#if isEditing}}
{{view Ember.TextField class='edit' action="updateWorkout"}}
{{else}}
{{#link-to 'workout' this}} {{title}} {{/link-to}}
{{/if}}
</li>
{{/each}}
<li>
{{newWorkoutName}}
</li>
</ul>
Controller:
EmberWorkouts.WorkoutsController = Ember.ArrayController.extend
actions:
editWorkout: (workout) ->
workout.set('isEditing', true)
createWorkout: ->
title = #get('newWorkoutName')
workout = #store.createRecord('workout', title: title)
#set('newWorkoutName', '')
workout.save()
updateWorkout: (workout) ->
workout.set('isEditing', false)
workout.save()
isEditing: false
Repo here if you want to investigate: https://github.com/ecl1pse/ember-workouts/tree/master/app
You can specify an itemController in your each and then use an ObjectController for each item in your list.
{{#each itemController="workout"}}
<li {{action editWorkout on="doubleClick"}}>
<!-- Other stuff goes here -->
</li>
{{/each}}
EmberWorkouts.WorkoutsController = Ember.ObjectController.extend({
editWorkout : function(){
this.set('isEditing', true);
}
});
Here's a JSBin of the general idea : http://jsbin.com/ucanam/1038/edit
I’ve been trying, using Rails/Ember pre-4, to do a fairly typical thing, that is have a page with a navbar and a content section. The navbar only changes on login (shows logout button when logged in and login and register buttons when logged out), not on every page change.
At first thought i could do something in the application.hbs template such as:
{{view navbar}}
{{outlet}}
where i set up navbar to respond to login state changes (managed by a state manager). This didn’t seem to work.
Then i tried something like (also in application.hbs):
{{outlet navbar}}
{{outlet}}
and tried setting navbar in each route, which results in lots of duplication and also didn’t ultimately work.
Before posting code, wanted to know if anyone already has a good solution to this common situation where certain parts of your page such as a navbar or sidebar only change upon some change in app state, not on every page change.
There are lots of ways to get this done. The first approach you described is closest to what we are doing. In past ember versions we used view helper for this, today we use {{render}} but it's the same basic concept. For example, application.hbs might look like this:
{{render navbar}} {{outlet}}
Now navbar.hbs can use a simple {{#if}} helper to swap links based on login state.
<div class="navbar">
<div class="navbar-inner">
{{#linkTo index class="brand"}}My App{{/linkTo}}
<ul class="nav">
<li>{{#linkTo index}}Home{{/linkTo}}</li>
<li>{{#linkTo about}}About{{/linkTo}}</a></li>
</ul>
<ul class="nav pull-right">
{{#if isAuthenticated}}
<li><a {{action logout}} href="#">Logout</a></li>
{{else}}
<li><a {{action login}} href="#">Login</a></li>
{{/if}}
</ul>
</div>
</div>
Now we add logic to NavbarController that tracks and manages login state.
App.NavbarController = Ember.ArrayController.extend({
isAuthenticated: false,
login: function() {
this.set('isAuthenticated', true);
},
logout: function() {
this.set('isAuthenticated', false);
}
});
In a real app NavbarController would proxy these requests to another controller, perhaps currentUserController. I've created a working sample here: http://jsbin.com/iyijaf/6/edit
I have the following code in a ember.js template. userController is an ArrayController, with multipe "users" within.
{{#each CollaborativeEditor.userController}}
{{#view CollaborativeEditor.OnlineUserView userBinding="this"}}
<div class="avatar">
<div class="avatar_name">{{name}}</div>
<div class="avatar_status">{{status}}</div>
</div>
<div id="dropdown-1">
<ul>
<li><a href="#" {{action startChat target="onlineUser"}}>Talk to </a></li>
</ul>
</div>
{{/view}}
{{/each}}
This is the code of the respective view:
CollaborativeEditor.OnlineUserView = Ember.View.extend({
tagName: 'li',
startChat : function() {
console.log(this.get('user'));
}
});
Although, the name and status is set correctly for each user, the startChat action attached to the link always prints the first user of the array to the console.
What is wrong with the binding ?
Thanks a lot for your request, to put it in a jsfiddle !
While I was trying to reproduce the error there, I realized the problem, and it has nothing to do with ember.
The div with id="dropdown-1" was called from another link and it was always the same id, therefore always the same action with its user-binding.
Now I've bound the Id to the user-object and it works perfectly.