EmberJS 2.7 - how to bind attribute 'disabled' for a button

徘徊边缘 提交于 2019-12-23 22:20:10

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!