Ernie
Ernie

Reputation: 1000

Ember js: parentViewDidChange doesn't get triggered

If have a little game where images have to be dragged on the right hotspots of a larger image.

The little images are inside a containerView, the hotspots also are ContainerViews. When i drop the images on a hotspot i use the following code in my drag-n-drop mixin to move the image in the dom:

Player.Droppable = Ember.Mixin.create({
    drop: function(event) {
        //get the view that was dragged
        var viewId = event.originalEvent.dataTransfer.getData('Text');
        var view = Ember.View.views[viewId];

        //log the parent-view: App.AnswerListView
        console.log(view.get('parentView').constructor);

        //detach the view from the original containerView
        var parentView = view.get('parentView');
        parentView.removeObject(view);

        //attach it to the hot-spot-containerview
        this.addObject(view);

        //logging this gives a different result: App.HotspotView
        console.log(view.get('parentView').constructor);

        event.preventDefault();
        return false;
    }
});

The view i'm dragging is an App.AnswerView. What i'm expecting from the docs is that the function parentViewDidChange on the AnswerView is triggered, but that doesn't happen:

App.AnswerView = Ember.View.extend(App.Draggable, {
    templateName: "answer",
    classNameBindings: [':answer', 'this.content.isSelected:selected'],
    click: function(evt){
        this.get('controller').send('answerClicked', this.content);
    },
    parentViewDidChange: function(){
        this.get('controller').send('answerMoved', this.content);
    },
});

The docs say: Called when the parentView property has changed. In my case, it is changed. Is this a bug, or am I missing something here?

TIA

Upvotes: 0

Views: 376

Answers (2)

Ernie
Ernie

Reputation: 1000

This issue was a bug and got resolved in the 1.0.0 final https://github.com/emberjs/ember.js/issues/2423

Upvotes: 1

Georgi Atsev
Georgi Atsev

Reputation: 3045

pushObject and removeObject are methods, inherited from the Ember.MutableArray Mixin, that the Ember.ContainerView extends. If you look at Ember's source code for ContainerView (https://github.com/emberjs/ember.js/blob/v1.0.0-rc.2/packages/ember-views/lib/views/container_view.js#L15), you will see that ContainerView does not override those methods, thus they only manipulate its childViews array, not the view's parent view. You should find methods that manipulate the '_parentView' property here instead: (https://github.com/emberjs/ember.js/blob/v1.0.0-rc.2/packages/ember-views/lib/views/view.js#L2018) - in the Ember.View's implementation. So in short, use:

  • removeChild instead of removeObject, to delete a child view from your ContainerView
  • createChildView + pushObject instead of 'addObject', if you want to add a new child view to a ContainerView.

Example Code:

Player.Droppable = Ember.Mixin.create({
    drop: function(event) {
        //get the view that was dragged
        var viewId = event.originalEvent.dataTransfer.getData('Text');
        var view = Ember.View.views[viewId];

        //log the parent-view: App.AnswerListView
        console.log(view.get('parentView').constructor);

        //detach the view from the original containerView
        var parentView = view.get('parentView');
        parentView.removeChild(view);

        //attach it to the hot-spot-containerview
        this.createChildView(view);
        this.pushObject(view);

        //logging this gives a different result: App.HotspotView
        console.log(view.get('parentView').constructor);

        event.preventDefault();
        return false;
    }
});

Upvotes: 0

Related Questions