0
votes

Here's a jsbinshowing the problem, however, it doesn't identify the error in the same way as on my computer. On my computer, I am told that Uncaught Error: childViews is immutable.

I am trying to add a childview to a containerView upon a click event, but I'm told that childviews (an array of views on containerView) are immutable. Can you explain how to add a childView to a containerView? I also tried appendChild but there's an error message that it can't be called during the rendering process.

In older versions of Ember, you used to be able to push objects onto the childViews array, for example, as this jsfiddle shows but the api appears to have changed.

If it's impossible, how to create this ui without pushing to the childViews array on a containerView?

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

App.MainView = Em.View.extend({
    classNames: ['mainView']
});

App.MyContainerView = Em.ContainerView.extend({});

App.AnotherView = Em.View.extend({
    render: function(buffer){
        buffer.push('App.AnotherView ' + this.get('elementId'));
    }
});

App.AddChildViewButton = Em.View.extend({
    tagName: 'button',
    render: function(buffer) {
        buffer.push('Add Child View');
    },
    click: function() {
        var containerView = Em.View.views['my_container_view']
        var childView = containerView.createChildView(App.AnotherView);
        containerView.get('childViews').pushObject(childView);
    }
});

template

<script type="text/x-handlebars" >
    {{#view App.MainView}}
      <h1>Hello world!</h1>
      <br>
      {{view App.AddChildViewButton}}    
      <br>
      {{view App.MyContainerView elementId="my_container_view"}}
    {{/view}}
</script>
1

1 Answers

0
votes

As shown in the documentation for Ember.ContainerView, you can add child views to a container view by pushing objects to the view itself, not to its childViews property:

click: function() {
    var containerView = Em.View.views['my_container_view']
    var childView = containerView.createChildView(App.AnotherView);

    // no need for .get('childViews')
    containerView.pushObject(childView);
}

Here is one of from the documentation that shows this (there is one other example there that uses this.pushObject(...) inside an init method):

var container = Ember.ContainerView.create();
container.append();

var firstView = App.FirstView.create(),
    secondView = App.SecondView.create();

container.pushObject(firstView);
container.pushObject(secondView);

And here is a jsBin with the example from your question functioning as intended:

http://jsbin.com/ciwonuqezi/3/

A bit more info:

The link you provided does indeed say that childViews is writable in ContainerView and shows an example of adding a view to childViews. It looks like this was deprecated in favor of the current approach in 1.0 and the information on that page is just outdated.

This page, for example, says:

ContainerView’s childViews is deprecated

This is another change that will result in a lot less code. Previously, if you had a ContainerView, you could add and remove views from it using the childViews proeprty. Now, the childViews property has been deprecated as the ContainerView itself acts like an Array. So instead of:

It looks like at some point Ember provided a deprecation notice and allowed the action when trying to modify a ContainerView's childViews:

ret.replace = function (idx, removedCount, addedViews) {
  if (view instanceof Ember.ContainerView) {
    Ember.deprecate("Manipulating an Ember.ContainerView through its childViews property is deprecated. Please use the ContainerView instance itself as an Ember.MutableArray.");
    return view.replace(idx, removedCount, addedViews);
  }
  throw new Ember.Error("childViews is immutable");
};

but it appears that this has since been removed and it now just throws the error you saw.