2

I've this code (http://jsfiddle.net/stephane_klein/gyHmS/2/) :

App = Ember.Application.create({});

App.Item = Ember.Object.extend({
    title: null,
    parent: null
});

App.MyList = Ember.Object.extend({
    title: null,
    content: [],
    changed: function() {
        console.log('here');
    }.observes('content')
});

App.list = App.MyList.create({
    title: "foobar",
    content: [
        App.Item.create({
            item: "item1"
        }),
        App.Item.create({
            item: "item2"
        })
    ]
});
console.log(App.list.content);

App.list.content.pushObject(
    App.Item.create({
        item: "item3"
    })
);
console.log(App.list.content);

Why "console.log('here')" is never called ?

I want set App.Item.parent when App.Item is inserted in App.MyList. I don't know how to observe App.MyList.content field.

Thanks for your help.

Best regards, Stephane

1 Answer 1

6

You're not changing the content property, you're just pushing an object in there. You have two solutions:

  • You can observe each item of the content (using .observes('content.@each')), but take attention, the method could be called several times
  • Or manually notify that this property has changed (using this.notifyPropertyChange('content'))

Here is the first solution: jsfiddle using @each

And here is the second solution: jsfiddle using notifyPropertyChange

You also have to notice you should not use directly App.list.content but App.list.get('content') instead. Take a look at this article written by Roy Daniels if you want more information.

EDIT

Please notice the use of @each has slightly changed. The Ember.Array#@each documentation says:

Returns a special object that can be used to observe individual properties on the array. Just get an equivalent property on this object and it will return an enumerable that maps automatically to the named key on the member objects.

If you merely want to watch for any items being added or removed to the array, use the [] property instead of @each.

Lets see that with an example:

App.Post = Ember.Object.extend({
  createdAt: null
});

App.Blog = Ember.Object.extend({
  posts: null,

  init: function() {
    this._super();
    this.set 'posts', [];
  },

  newerPost: function() {
    return this.get('posts').sortBy('createdAt').get('firstObject');
  }.property('[email protected]'),

  postsCount: function() {
    return this.get('posts.length');
  }.property('posts.[]')
});

newerPost needs to observes a particular property of each posts, whereas postsCount just needs to know when the posts array changes.

Sign up to request clarification or add additional context in comments.

2 Comments

'content.@each' is working if the content is a "simple" object... but how to do the same if the object is a "complex" object (Person: firstName, lastName) ??? it seems that .observes('content.firstName.@each') is not working...
content.@each is working only if the content is an array (see the source code: github.com/emberjs/ember.js/blob/v1.0.0-pre.2/packages/…). You don't need it for non-array objects, you can just use .observes('content.firstName') for observing the firstName property of the content

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.