0
votes

I'm trying to set a default value of a property, depending on another property of the model being loaded.

How do I trigger the setOthers method, after the model has loaded? The totalPoints property can change afterwards, and the user should also be able to change the others value, from the initial value set in the setOthers method.

I have this User model:

App.User = DS.Model.extend(
  # [ ... ]
  competenceRatings: DS.attr('competenceRatings')
)

Here's the controller:

App.UsersEditController = Ember.ObjectController.extend(
  others: 0 # Set others to remaining points, if points > 0 and less than 100.

  totalPoints: (->
    totalPoints = @get('others')
    totalPoints += competenceRating.get('points') for competenceRating in @get('competenceRatings')
    totalPoints
  ).property('competenceRatings.@each.points', 'others')

  setOthers: ->
    totalPoints = @get('totalPoints')
    if totalPoints > 0 and totalPoints < 100
      @set('others', 100 - totalPoints)
)

I already tried http://emberjs.com/api/#method_computed_defaultTo:

App.UsersEditController = Ember.ObjectController.extend(
  others: Ember.computed.defaultTo('setOthers') # Set others to remaining points, if points > 0 and less than 100.

  totalPoints: (->
    totalPoints = @get('others')
    totalPoints += competenceRating.get('points') for competenceRating in @get('competenceRatings')
    totalPoints
  ).property('competenceRatings.@each.points', 'others')

  setOthers: (->
    console.log @get('isLoaded')
    value = 0
    totalPoints = @get('totalPoints')
    if totalPoints > 0 and totalPoints < 100
      #@set('others', 100 - totalPoints)
      value = 100 - totalPoints
    value
  ).property()
)

Here's the output:

true employeenet.js:105386
true employeenet.js:105386
[ ... repeated many, many... many times ... ]
true employeenet.js:105386
<error> VM1936:1
<error> VM1936:1
Uncaught RangeError: Maximum call stack size exceeded employeenet.js:1
Error: Assertion Failed: Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property change notifications.
    at new Error (native)
    at Error.Ember.Error (http://localhost:3000/assets/employeenet.js:47844:19)
    at Object.Ember.assert (http://localhost:3000/assets/employeenet.js:47073:11)
    at Object.Ember.merge.empty (http://localhost:3000/assets/employeenet.js:71691:11)
    at Ember.CollectionView.Ember.ContainerView.extend.arrayWillChange (http://localhost:3000/assets/employeenet.js:72618:25)
    at Object.sendEvent (http://localhost:3000/assets/employeenet.js:49537:14)
    at Ember.Array.Ember.Mixin.create.arrayContentWillChange (http://localhost:3000/assets/employeenet.js:62031:11)
    at Ember.ArrayProxy.Ember.Object.extend.arrangedContentArrayWillChange (http://localhost:3000/assets/employeenet.js:66416:10)
    at null._arrangedContentWillChange (http://localhost:3000/assets/employeenet.js:66266:10)
    at sendEvent (http://localhost:3000/assets/employeenet.js:49537:14) employeenet.js:50461
Uncaught Error: Assertion Failed: Error: Assertion Failed: Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property ...<omitted>...s. employeenet.js:47073
Error: Assertion Failed: Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property change notifications.
    at new Error (native)
    at Error.Ember.Error (http://localhost:3000/assets/employeenet.js:47844:19)
    at Object.Ember.assert (http://localhost:3000/assets/employeenet.js:47073:11)
    at Object.Ember.merge.empty (http://localhost:3000/assets/employeenet.js:71691:11)
    at Ember.CollectionView.Ember.ContainerView.extend.arrayWillChange (http://localhost:3000/assets/employeenet.js:72618:25)
    at Object.sendEvent (http://localhost:3000/assets/employeenet.js:49537:14)
    at Ember.Array.Ember.Mixin.create.arrayContentWillChange (http://localhost:3000/assets/employeenet.js:62031:11)
    at Ember.ArrayProxy.Ember.Object.extend.arrangedContentArrayWillChange (http://localhost:3000/assets/employeenet.js:66416:10)
    at null._arrangedContentWillChange (http://localhost:3000/assets/employeenet.js:66266:10)
    at sendEvent (http://localhost:3000/assets/employeenet.js:49537:14) employeenet.js:50461
Uncaught Error: Assertion Failed: Error: Assertion Failed: Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property ...<omitted>...s. employeenet.js:47073
1

1 Answers

0
votes

Check out Ember.computed.defaultTo.

Something like this should work:

App.UsersEditController = Ember.ObjectController.extend(
  others: Ember.computed.defaultTo('othersDefault')

  totalPoints: (->
    totalPoints = @get('others')
    totalPoints += competenceRating.get('points') for competenceRating in @get('competenceRatings')
    totalPoints
  ).property('competenceRatings.@each.points', 'others')

  othersDefault: (->
    totalPoints = @get('totalPoints')
    if totalPoints > 0 and totalPoints < 100
      @set('others', 100 - totalPoints)
  ).property()