问题
This official guide describes how you can bind a boolean property to disabled attribute of a HTML element. Yet it talks about a controller.
I have a button, that when clicked transitions the route (sorry it has to be a button and cannot be a link-to):
/templates/trails.hbs
<button type="button" class="btn btn-primary" disabled={{isEditing}}
onclick={{route-action 'addNew'}}>Add New</button>
(route-action is a helper that allows me to use closure actions in routes)
/routes/trails.js
import Ember from 'ember';
export default Ember.Route.extend({
actions: {
addNew() {
this.transitionTo('trails.new');
}
}
});
So, after the button is clicked, the route is changed to 'trails.new'
/routes/trails/new.js
import Ember from 'ember';
export default Ember.Route.extend({
isEditing: true,
});
This property appears to be ignored and is not bound as I had expected it would be. I also tried adding a controller:
/controllers/trails/new.js
import Ember from 'ember';
export default Ember.Controller.extend({
isEditing: true,
});
So how does the official guide suggest something that seems to not work? What piece of ember magic am I missing here?
回答1:
Your template is templates/trails.hbs
but you set isEditing
in a subroute controller controllers/trails/new.js
You need to have controllers/trails.js
and deinfe isEditing
in it.
So in routes/trails.js
implement this :
actions: {
willTransition: function(transition) {
if(transtions.targetName === 'trails.new'){
this.controller.set('isEditing', true);
}
else{
this.controller.set('isEditing', false);
}
}
}
回答2:
After some digging around I discovered that what I was trying to do is not the right way to go about this at all. I would have to add a controller/trails.js and put the property 'isEditing' in that.
So I refactored this into a component: add-new-button. This is a far more 'ember' way.
First, I need an initializer (thanks to this question):
app/initializers/router.js
export function initialize(application) {
application.inject('route', 'router', 'router:main');
application.inject('component', 'router', 'router:main');
}
export default {
name: 'router',
initialize
};
(this injects the router into the component, so I can watch it for changes and also 'grab' the currentRoute)
My code refactored into the component:
app/components/add-new-button.js
import Ember from 'ember';
export default Ember.Component.extend({
isEditing: function() {
let currentRoute = this.get('router.currentRouteName');
return ~currentRoute.indexOf('new');
}.property('router.currentRouteName')
});
templates/components/add-new-button.hbs
<button type="button" class="btn btn-primary" disabled={{isEditing}}
onclick={{route-action 'addNew'}}>Add New</button>
templates/trails.hbs
{{add-new-button}}
The beauty of this is now I can use this button on my other top level templates to trigger route changes to the new route for each resource (and disable the button on arrival at the new route).
NOTE
return ~currentRoute.indexOf('new');
is doing a substring check on the route, if it finds 'new' returns true, otherwise returns false. See this.
In ES6 it can be replaced with (so I have!):
return currentRoute.includes('new);
来源:https://stackoverflow.com/questions/39395911/emberjs-2-7-how-to-bind-attribute-disabled-for-a-button