Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I programmatically add child views to an Ember view at specific DOM selectors?

Tags:

ember.js

I have a view that uses a 3rd party library to render additional DOM elements in the didInsertElement hook. After these new elements are added, I need to add some child views inside them, so that they can render dynamic data.

Here's what I tried:

App.MyView = Ember.View.extend({
  didInsertElement: function() {
    create3rdPartyDomElements();
    var element = this.$('someSelector');
    childView = this.createChildView(App.SomeViewClass, attributesDict);
    childView.appendTo(element);
  }
});

(jsbin: http://jsbin.com/idoyic/3)

This renders my views as expected, but gives the following assertion error with Ember RC 7: "You cannot append to an existing Ember.View. Consider using Ember.ContainerView instead."

I have tried extending ContainerView, as advised here and that works, but I have no way of inserting the child views at specific DOM selectors. It just inserts the child views at the beginning of the parent view.

Can someone please help me? Thanks a lot!

like image 895
Andrei Soare Avatar asked Aug 15 '13 19:08

Andrei Soare


1 Answers

This is how I created:

An implementation where you have the main view, in that case codemirror, in the middle. And it's possible add more views, in the top or bottom.

App.EditorView = Ember.View.extend({
  templateName: 'editor-view',
  topView: Ember.ContainerView.extend(),
  bottomView: Ember.ContainerView.extend(),
  CodeMirrorView: Ember.TextArea.extend({  
    didInsertElement: function() {      
      this.codeMirror = CodeMirror.fromTextArea(this.get('element'));                  
    }
  })
});

The template:

<script type="text/x-handlebars" data-template-name="editor-view">
  {{view view.topView viewName="topViewInstance"}}
  {{view view.CodeMirrorView}}
  {{view view.bottomView viewName="bottomViewInstance"}}
</script>

A view to represent a custom component:

App.MyComponent = Ember.View.extend({
  templateName: 'click-here',
  message: null,
  click: function() {
    alert(this.get('message'));
  }
});

The implementation:

App.MyEditorView = App.EditorView.extend({  
  didInsertElement: function() {
    this._super();
    this.get('topViewInstance').pushObject(App.MyComponent.create({ message: "Hello" }));

    this.get('bottomViewInstance').pushObject(App.MyComponent.create({ message: "World" }));
  }
});

With this is possible to create a new instance, or extend App.EditorView and insert more views in top or bottom. Because the topView and bottomView are Ember.ContainerViews, all views added will have the bindings, events, and other ember features.

Give a look in that jsbin to see it working http://jsbin.com/ucanam/686/edit

like image 183
Marcio Junior Avatar answered Nov 11 '22 17:11

Marcio Junior