ember.jspropertiescomponentsember-1

How to change controller property from component?


I have a property in the controller. I want to use a component to update that controller property. The usual component parameter passing works when I'm using a text field like the guides say, but in my case, I'm changing the value in code, not input fields. The binding seems to be broken.

What method similar to propertyDidChange() or notifyPropertyChange() should I use to accomplish this? Can you also provide a simple example so I know WHERE to make that method call?

personalities controller

`import Ember from 'ember'`

PersonalitiesController = Ember.ArrayController.extend

  eiValue: ->
    if params.name
      params.name.charAt(0)
    else
      'e'

  nsValue: ->
    if params.name
      params.name.charAt(1)
    else
      'n'

  tfValue:  ->
    if params.name
      params.name.charAt(2)
    else
      't'

  pjValue:  ->
    if params.name
      params.name.charAt(3)
    else
      'p'

  type: (->
    this.get('eiValue') + this.get('nsValue') + this.get('tfValue') + this.get('pjValue')
  ).property('eiValue', 'nsValue', 'tfValue', 'pjValue')

  typeChanged: ((model, type)->
    Ember.run.once(this, 'routeToPersonality')
  ).observes('type')

  routeToPersonality: ->
    this.get('controller').transitionToRoute('personality', this.get('type'))

`export default PersonalitiesController`

personalities template

%dichotomy-selector type=type

component

`import Ember from 'ember'`

DichotomySelectorComponent = Ember.Component.extend
  eiValue: 'e'
  nsValue: 'n'
  tfValue: 't'
  pjValue: 'p'

  type: (->
    newValue = this.get('eiValue') + this.get('nsValue') + this.get('tfValue') + this.get('pjValue')
    this.set('controller.type', newValue)
  ).property('eiValue', 'nsValue', 'tfValue', 'pjValue')

  actions: 
    toggleEI: ->
      eiValue = this.get('eiValue')
      if eiValue == 'e'
        this.set('eiValue', 'i')
      else if eiValue == 'i'
        this.set('eiValue', 'e')

    toggleNS: ->
      nsValue = this.get('nsValue')
      if nsValue == 'n'
        this.set('nsValue', 's')
      else if nsValue == 's'
        this.set('nsValue', 'n')

    toggleTF: ->
      tfValue = this.get('tfValue')
      if tfValue == 't'
        this.set('tfValue', 'f')
      else if tfValue == 'f'
        this.set('tfValue', 't')

    togglePJ: ->
      pjValue = this.get('pjValue')
      if pjValue == 'p'
        this.set('pjValue', 'j')
      else if pjValue == 'j'
        this.set('pjValue', 'p')

`export default DichotomySelectorComponent`

Solution

  • You should be able to use this.set("controller.property", value) in a method inside the component, per the docs here: http://emberjs.com/api/classes/Ember.Component.html#property_controller

    Edit September 2016 This answer has been the victim of the ongoing evolution of Ember, and the associated changes in best practices. It is amazing to see how different Ember is from just 1.5 years ago. The old answer has been totally rejected by the community as evidenced by the votes (negative as I type this), in fact I don't think it even works anymore. As of mid-2016 in Ember 2.x the generally accepted answer to this question is to create an action in the controller that changes the property, pass that action to the component, and call the action when the value changes on the component. But now you can use the action helper to pass a regular method instead of an action, and use component life cycle hooks to detect changes in the component instead of using an observer or computed property. You could also use a service instead. More changes on the way, I am sure.

    For any future readers, any questions you need to research about Ember make sure that you filter results by time, you only want results within the last year.