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
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}}
Related
I watched a video lesson on vueschool and repeated the code as the teacher. But it doesn't work for me, and it works for him. In the browser console, it shows that there is no template indexer, but why does it all work?
HTML:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="app">
<p>Просто текст</p>
<click-counter></click-counter>
<click-counter></click-counter>
<click-counter></click-counter>
</div>
<script scr="vue.js"></script>
<script src="app.js"></script>
</body>
</html>
vue js
Vue.component ('click-counter', {
template: "<button #click="count++">{{count}}</button>",
data() {
return {
count: 0
}
}
})
new Vue ({
el: "#app"
})
In the component template, please use ' quotes to wrap the click function. Since you are using double quotes to wrap button, the same cannot be used in it which tends to close the first one.
Please find below the code
Vue.component('click-counter', {
template: "<button #click='count++'>{{count}}</button>",
data() {
return {
count: 0
}
}
})
new Vue({
el: "#app"
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.0/vue.js"></script>
<div id="app">
<click-counter/>
</div>
Change this line:
"<button #click="count++">{{count}}</button>"
Give this:
"<button #click='count++'>{{count}}</button>"
Make sure that, you have import vuejs in your file.
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
I'm creating a slider web component from scratch to learn.
I want the button to hide when the attribute controlVisible is false and show when it's true, but my selector $('#botaoVoltar') doesn't get anything.
What am I missing?
index.html:
<body>
<slider-js controlVisible='false' ></slider-js>
</body>
polymer.html:
<polymer-element name="slider-js">
<template>
<center>
<div id="container">
<div id="Buttons">
<button name="voltar" id="botaoVoltar"><<</button>
</div>
</div>
</center>
</template>
</polymer-element>
<script>
Polymer('slider-js', {
controlVisible: false,
ready: function () {
if (this.controlVisible === false) {
$('#botaoVoltar').hide();
} else {
$('#botaoVoltar').show();
}
}
});
</script>
The attribute is working fine. If I console.log it, I can see if it is true or false, but the template still renders with the button.
jQuery can't get at Polymer's local DOM, so you'd have to use Polymer's own DOM API. Actually, Polymer's automatic node finding provides quick access to nodes that have IDs with this.$. For instance, you could access the botaoVoltar button in your example with this.$.botaoVoltar.
It looks like you're using old Polymer (pre 1.0). You should switch to the latest version of Polymer (1.5.0). Here's your code upgraded to the newest Polymer version:
<head>
<base href="https://polygit.org/polymer+1.5.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
</head>
<body>
<span>With control-visible:</span>
<x-slider control-visible></x-slider>
<span>Without control-visible:</span>
<x-slider></x-slider>
<!-- Normally, you would define this element in its own file. -->
<dom-module id="x-slider">
<template>
<div id="container">
<div id="Buttons">
<button id="botaoVoltar"><<</button>
<button>>></button>
</div>
</div>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-slider',
properties : {
controlVisible: {
type: Boolean,
value: false
}
},
ready: function() {
this.$.botaoVoltar.hidden = !this.controlVisible;
}
});
});
</script>
</dom-module>
</body>
codepen
I am trying to trigger an event from an Ember.js controller. I throws an error saying "ember.min.js:3 Uncaught Error: Nothing handled the action 'clicked'. If you did handle the action, this error can be caused by returning true from an action handler in a controller, causing the action to bubble.". Also I am not clear on how the event system works on itself for the targeted action. C an someone help me with this. Here is my code:
<!DOCTYPE html>
<html>
<head>
<title>Ember.js Application example</title>
<!-- CDN's -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.1/handlebars.min.js"></script>
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ember.js/1.10.0/ember.min.js"></script>
<script src="http://builds.emberjs.com/tags/v1.10.0-beta.3/ember-template-compiler.js"></script>
<script src="http://builds.emberjs.com/release/ember.debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ember.js/2.4.3/ember.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container" id="github-app">
</div>
<script type="text/x-handlebars" data-template-name="application">
<div class="row">
<div class="col-md-12">
<h1>Hello from Ember!</h1>
{{outlet}}
</div>
</div>
</script>
<script type="text/x-handlebars" data-template-name="index">
<p>This is a github explorer for all the users.</p>
<ul>{{#each dev in controller}}
<li>{{dev}}</li>
{{/each}}
</ul>
<p>
<button class="btn btn-success" {{action "clicked"}}>Click Me</button>
</p>
<p>{{renderedOn}}</p>
</script>
<script type="text/javascript">
App = Ember.Application.create({
rootElement:"#github-app"
});
App.IndexRoute=Ember.Route.extend({
model:function(){
return [
"Sam",
"Sandy",
"Samudh"
];
}
});
App.IndexController = Ember.ArrayController.extend({
renderedOn : function(){
return new Date();
}.property(),
actions : {
clickMe(){
alert("I been clicked");
}
}
});
</script>
</body>
</html>
Also available at http://jsbin.com/cuxajiyuqa/edit?html,output
You don't have an action with the name 'clicked', and you tell your code to look for an action 'clicked' on clicking the button. Change
{{action "clicked"}}
into
{{action "clickMe"}}
or change the
clickMe(){
action into
clicked(){
and everything should be fine.
Check https://guides.emberjs.com/v2.4.0/templates/actions/ for the documentation on actions
Pretty simple test app, but for some reason, the template is not rendering and so far I just try one template only. Only blank page showing. no error
// The Application
// ---------------
// Our overall **AppView** is the top-level piece of UI.
app.AppMainView = Backbone.View.extend({
// Instead of generating a new element, bind to the existing skeleton of
// the App already present in the HTML.
el: '#nested-viewer',
view1Template: _.template( $('#view1').html() ),
view2Template: _.template( $('#view2').html() ),
view3Template: _.template( $('#view3').html() ),
// New
// Delegated events for creating new items, and clearing completed ones.
events: {
'keyup [nv-data="myinput"]': 'changedData',
},
// At initialization we bind to the relevant events on the `Todos`
// collection, when items are added or changed. Kick things off by
// loading any preexisting todos that might be saved in *localStorage*.
initialize: function() {
console.log("init")
this.dataStorage1=new app.dataStorage();
console.log(this.dataStorage1)
// this.listenTo(app.Fund, 'change',this.adjustAllDivison);
},
// New
// Re-rendering the App just means refreshing the statistics -- the rest
// of the app doesn't change.
render: function() {
this.$el.html(this.view1Template());
},
changedData: function(){
console.log("changedData");
},
resetAllDivison: function(){
console.log("resetAllDivison")
},
});
// js/app.js
var app = app || {};
$(function() {
// Kick things off by creating the **App**.
new app.AppMainView();
});
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Nested View</title>
<link rel="stylesheet" href="src/app/style.css">
<link rel="stylesheet" href="/library/dragdealer/0.9.8/css/dragdealer.css">
</head>
<body>
<div id="nested-viewer">
</div>
<!-- Templates -->
<script type="text/template" id="view1">
<div class="view1s">
<input nv-data="myinput" type="text" id="input1" name="" value="123" placeholder="">
</div>
</script>
<script type="text/template" id="view2">
<div class="view2s">
<p id="display2">View 2 </p>
</div>
</script>
<script type="text/template" id="view3">
<div class="view3s">
<p id="display3">View 3</p>
</div>
</script>
<!-- Loading Templates + Vendor Scripts -->
<script type="text/template" id="item-template"></script>
<!-- Addons -->
<script src="/library/dragdealer/0.9.8/js/dragdealer.js"></script>
<!-- Main Framework -->
<script src="src/assets/lib/jquery.js"></script>
<script src="src/assets/lib/underscore.js"></script>
<script src="src/assets/lib/backbone.js"></script>
<script src="src/assets/lib/backbone.localStorage.js"></script>
<!-- Modules -->
<!-- Main -->
<!-- Nested View -->
<script src="src/app/modules/NestedView/models/dataStore.js"></script>
<script src="src/app/modules/NestedView/views/AppMainView.js"></script>
<!--
<script src="src/app/modules/NestedView/views/view1.js"></script>
<script src="src/app/modules/NestedView/views/view2.js"></script>
<script src="src/app/modules/NestedView/views/view3.js"></script>
-->
<!-- App Base -->
<script src="src/app/router.js"></script>
<script src="src/app/app.js"></script>
</body>
</html>
You actually don't append the View's el to DOM. You don't even call the view instance's render method. You could do it on initialization, i.e. in your initialize method or after creating the instance.
var mainView = new app.AppMainView();
mainView.render();
mainView.$el.appendTo(document.body);
Edit: I just noticed that you are passing a selector to the view (el: '#nested-viewer'). This means that just need to call the render method as the element exists in the DOM.
In my code below I am trying to load the 'home' route template as my index route?
how do I do this? go to mysite.com then the home route template must load only?
I don't want to see the application template and use its {{outlet}}.
Thanks for your help
var App = Ember.Application.create();
App.Router.map(function(){
this.resource('home', {path: ''} );
//this.resource('home', {path: '/h'} );
this.resource('about', {path: '/a'} );
this.resource('contact', {path: '/c'} );
});
App.ApplicationRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('contact');
}
});
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('home');
}
});
App.HomeRoute = Ember.Route.extend({
});
App.AboutRoute = Ember.Route.extend({
});
App.ContactRoute = Ember.Route.extend({
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
</head>
<body>
<script src="js/libs/jquery-1.10.2.js"></script>
<script src="js/libs/handlebars-1.1.2.js"></script>
<script src="js/libs/ember-1.5.1.js"></script>
<script src="js/attempt1.js"></script>
<script type="text/x-handlebars">
<div>
page - Application
</div>
{{outlet}}
</script>
<script type="text/x-handlebars" id="home">
<div>
page - Home
</div>
</script>
<script type="text/x-handlebars" id="about">
<div>
page - About
</div>
</script>
<script type="text/x-handlebars" id="contact">
<div>
page - Contact
</div>
</script>
</body>
</html>
change id for data-template-name :
<script type="text/x-handlebars" data-template-name="home">
<div>
page - Home
</div>
</script>