0
votes

I got an error when I want try to add a component into a div DOM in another component.

Uncaught Error: Assertion Failed: You cannot append to an existing Ember.View. Consider using Ember.ContainerView instead.

here is my JSBin

App = Ember.Application.create();

App.MyListComponent= Ember.Component.extend({
  layoutName:'my-list',
  actions:{
  addItem:function(){
   console.log("add item action");
   
 App.MyListItemComponent.create().appendTo("#holder");
  },
  },
});
App.MyListItemComponent= Ember.Component.extend({
  layoutName:'my-list-item',
});
html, body {
  margin: 20px;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Ember Starter Kit</title>
  <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.1/normalize.css">
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
  <script src="http://builds.emberjs.com/release/ember-template-compiler.js"></script>
  <script src="http://builds.emberjs.com/release/ember.debug.js"></script>
</head>
<body>

  <script type="text/x-handlebars">
    <h2>Welcome to Ember.js</h2>

    {{outlet}}
  </script>

  <script type="text/x-handlebars" data-template-name="index">
    {{my-list}}
  </script>

<script type="text/x-handlebars" id="my-list">
<button {{action "addItem"}}>add item</button>
    This is a holder:
    <div id="holder">
      i am inside holder
    </div>
    
    This is static item:
    {{my-list-item}}
  </script>
  
  <script type="text/x-handlebars" id="my-list-item">
i am a list item
  </script>
  
</body>
</html>

can you have a look and tell me how to do?

thank you very much

1
I do not have an answer to your immediate question but I am wondering if you could rethink your approach. Instead of thinking in terms of mutating the DOM, I believe you should be thinking in terms of mutating the data that the DOM is bound to. You can have a collection of items and display a my-list-item for each one. Then, the addItem action can mutate the underlying collection, adding a value. I believe this approach would just "just work" and is more in line with Ember's way of thinking but I could be missing something about your use case. - Oren Hizkiya

1 Answers

1
votes

I dont think, your approach is right. A component should be working independently from the context in which it is added. You can pass anything as argument to the component within the template. I would recommend displaying the components depending on some type of model that is added with each addItem click (in my example, a simple text). Why don't you try it this way:

JS

App = Ember.Application.create();

App.MyListComponent= Ember.Component.extend({
components: Ember.A([]),
layoutName:'my-list',
actions:{
    addItem:function(){
        var components = this.get('components');
        console.log(components);
        components.pushObject ('test'); // or whatever you want: could also be components.pushObject(App.MyListItemComponent.create()); if you want to use it later somehow. 
        this.set('components', components);
        console.log("add item action");
    },
},
});
App.MyListItemComponent= Ember.Component.extend({
layoutName:'my-list-item',
});

html

<script type="text/x-handlebars" id="my-list">
<button {{action "addItem"}}>add item</button>
This is a holder:
<div id="holder">
    i am inside holder {{components.length}}
    {{#each components as |item|}}
        {{my-list-item}}
    {{/each}}

</div>

This is static item:
{{my-list-item}}