Why the index template hide application template elements in emberJS app - ember.js

I have a index.html like folows
<body>
<script type="text/x-handlebars" data-template-name="application">
<h2> Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<h2> Welcome to index</h2>
</script>
</body>
In browser, I see only "Welcome to index" why not
Welcome to Ember.js
Welcome to index
My route related code is
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({ });
My view related code is
App.ApplicationView = Ember.View.extend({
templateName:'index'
});
I use the following js
head.load("css/style.css",
"js/libs/jquery/jquery-1.10.2.js",
"js/libs/jquery/jquery-ui-1.10.4.js",
"js/libs/jquery/jquery.sizes.js",
"js/libs/jlayout/jlayout.border.js",
"js/libs/jlayout/jquery.jlayout.js",
"js/libs/jquery/mutate/mutate.events.js",
"js/libs/jquery/mutate/mutate.js",
"js/libs/handlebars-1.3.0.js",
"js/libs/ember/ember-1.6.1.js",
"js/app.js",
"js/views/applicationView.js"
);
I have seen that if I have removed
templateName:'index'
from
App.ApplicationView
the index template have not remmoved the application template elements but throw a bug
DEBUG: -------------------------------
DEBUG: Ember : 1.6.1
DEBUG: Handlebars : 1.3.0
DEBUG: jQuery : 1.10.2
DEBUG: -------------------------------
debug:
generated -> route:application Object { fullName="route:application"}
generated -> route:index Object { fullName="route:index"}
generated -> controller:application Object { fullName="controller:application"}
Rendering application with <App.ApplicationView:ember212> Object {
fullName="view:application"}
generated -> controller:index Object { fullName="controller:index"}
Rendering index with default view <Ember._MetamorphView:ember228> Object {
fullName="view:index"}
Transitioned into 'index'
TypeError: document.getElementById(...) is null
document.getElementById( this.morph.start ).parentNode ===
ember-1.6.1.js (line 32241)

Related

Appending Ember Component to a DOM element not managed by Ember

I would like to append an Ember Component ComponentB to a DOM element which is generated by some non-Ember UI library on didInsertElement of ComponentA, resulting in something like
<div class='ember-view component-a'>
<div class='i-know-nothing-of-ember'>
<div class='ember-view component-b'></div>
</div>
</div>
I am aware of appendTo(element) method, however it fails with assertion
You cannot append to an existing Ember.View. Consider using Ember.ContainerView instead.
I also tried calling createElement on component B and then appending it to DOM via jQuery - which kind of works, however in the end it fails with error
Cannot set property '_elementInserted' of null
See http://emberjs.jsbin.com/cofebo/2/
What is the proper way to achieve the above; if possible actions and other behaviours should be as if i-know-nothing-of-ember would be generated by Component A template.
I suggest using the container to lookup the component and append it anywhere whenever you need to.
Approach 1 - retrieve container within route
http://emberjs.jsbin.com/libipazavu/1/edit?html,js,output
js
App = Ember.Application.create();
App.IndexRoute = Em.Route.extend({
setupController:function(controller,model){
controller.set("container",this.container);
}
});
App.IndexView = Em.View.extend({
appendNonEmberUILibrary:function(){
callNonEmberUILibrary();
var componentB = this.get("controller.container").lookup("component:component-b");
componentB.appendTo(".non-ember-ui");
}.on("didInsertElement")
});
App.ComponentBComponent = Em.Component.extend({
layoutName:"components/component-b",
prop1:"test-option-1"
});
function callNonEmberUILibrary(){
$("body").append("<div class='non-ember-ui' style='border:1px solid;'>element from non-ember ui lib</div>");
}
hbs
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
<h3>Adding Ember Component to non-Ember DOM Element using <u><i>container</i></u></h3>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="components/component-b">
<br/>
<div style="border:1px dashed #F5664D">
This is componentB -> {{prop1}}
</div>
<br/>
</script>
Approach 2 - retrieve container within an initializer
http://emberjs.jsbin.com/hijedowacu/1/edit?html,js,output
js
App = Ember.Application.create();
App.initializer({
name:"main",
initialize:function(container,application){
application.register('main:compB', container.lookup("component:component-b"), { instantiate: false });
application.inject("controller:index","theComponentB","main:compB");
}
});
App.IndexView = Em.View.extend({
appendNonEmberUILibrary:function(){
callNonEmberUILibrary();
var componentB = this.get("controller.theComponentB");
componentB.appendTo(".non-ember-ui");
}.on("didInsertElement")
});
App.ComponentBComponent = Em.Component.extend({
layoutName:"components/component-b",
prop1:"test-option-1"
});
function callNonEmberUILibrary(){
$("body").append("<div class='non-ember-ui' style='border:1px solid;'>element from non-ember ui lib</div>");
}
hbs
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
<h3>Adding Ember Component to non-Ember DOM Element using <u><i>container</i></u></h3>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="components/component-b">
<br/>
<div style="border:1px dashed #F5664D">
This is componentB -> {{prop1}}
</div>
<br/>
</script>
Approach3 - reallocate added component with jquery (update from comments)
Alternatively you could just add the component-b in the template as non visible and within didInsertElement you could reallocate and display it wherever required using jquery.
example http://jsbin.com/maginovexa/1/edit?html,js,output
js
App.IndexView = Em.View.extend({
prop2:"prop-from-index-view",
appendNonEmberUILibrary:function(){
callNonEmberUILibrary();
//var componentB = this.get("controller.container").lookup("component:component-b");
//componentB.appendTo(".non-ember-ui");
var componentBDOM = this.get("componentB").$().detach();
$(".non-ember-ui").append(componentBDOM);
}.on("didInsertElement"),
click:function(){this.set("prop2",Date.now());}
});
App.ComponentBComponent = Em.Component.extend({
layoutName:"components/component-b",
prop1:"test-option-1"
});
function callNonEmberUILibrary(){
$(".inner").append("<div class='non-ember-ui' style='border:1px solid;'>element from non-ember ui lib</div>");
}
hbs
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
<h3>Adding Ember Component to non-Ember DOM Element using <u><i>container</i></u></h3>
<div class='inner'></div>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
this is index (click here to change prop2 of component)
<div style="display:none">
{{component-b prop2=view.prop2 viewName="componentB"}}
</div>
</script>
....
This is a fully working solution for reallocating an ember controlled element to a non-ember element that is within an ember view, as requested by Simon Jesenko (the op).
Have you tried the run loop? Like this,
//after comp.createElement();
parent = this;
Ember.run.schedule('afterRender', this, function() {
parent.$('.i-know-nothing-of-ember').append($(comp.element));
});

Does not rendering index with default view in ember-1.6.1

As-salamu-wa-alicum
Every body,
I have a index.html with
<script type="text/x-handlebars" data-template-name="application">
<div id="tabcontent" class="post" contenteditable="true">
{{outlet}}
</div>
</script>
applicationView.js with
App.applicationView = Ember.View.extend({
template:Ember.Handlebars.compile('welcomeTemplate.hbs')
,templateName:'application'
});
In js/templates/welcomeTemplate.hbs is
<div><p>Welcome</p></div>
In app.js I have
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({ });
In console log I am getting
DEBUG: -------------------------------
DEBUG: Ember : 1.6.1
DEBUG: Handlebars : 1.1.2
DEBUG: jQuery : 1.10.2
DEBUG: -------------------------------
generated -> route:application Object { fullName="route:application"}
generated -> route:index Object { fullName="route:index"}
generated -> controller:application Object { fullName="controller:application"}
Rendering application with default view <(subclass of Ember.View):ember211> Object {
fullName ="view:application"}
generated -> controller:index Object { fullName="controller:index"}
**Could not find "index" template or view. Nothing will be rendered Object {
fullName="template:index"}**
log:
Transitioned into 'index'
Please tell me what is going on here and why am I not see the "Welcome" in browser at /index.html? How will I see "Welcome" in browser at /index.html?
Thank you very much
With best regards
Nadvi.
It doesn't make sense to have both a template and a templateName. Additionally application should be uppercase.
App.ApplicationView = Ember.View.extend({
template:Ember.Handlebars.compile('Hello {{name}}<br/>Name: {{input value=name}}')
});
Ember doesn't load files for you, so stating a hbs name won't do anything, it'll just think of it as a plain string you wanted to show in the page.
http://emberjs.jsbin.com/joyiqute/1/edit

Accessing a single record from a simple model

I'm starting simple, trying to display a single value from a simple model.
This answer to "accessing the model from the template" suggests that it's necessary to extend ObjectController. At this point, there's have no application logic, so it doesn't seem like a controller (or a view) is really needed yet.
Likewise, there are no routes yet, so it doesn't seem like anything should be needed beyond App.IndexRoute.
The single object in the dictionary fixture has a title property with the value Hello Ember. I'm expecting to see that text displayed between two hard-coded arrows. Instead, all I get is the arrows.
The Index.html is:
<!DOCTYPE html>
<html>
<head>
<title>Dictionary</title>
</head>
<body>
<!-- Main body of the application -->
<script type="text/x-handlebars">
<p>Title: -->{{title}}<--</p>
</script>
<!-- ... Ember.js and other JavaScript dependencies ... -->
<script src="js/libs/jquery-1.10.2.min.js"></script>
<script src="js/libs/handlebars-1.0.0.js"></script>
<script src="js/libs/ember.js"></script>
<script src="js/libs/ember-data.js"></script>
<script src="js/app/application.js"></script>
<script src="js/routers/router.js"></script>
<script src="js/models/dictionary_model.js"></script>
<script src="js/controllers/dictionary_controller.js"></script>
</body>
</html>
And then the JavaScript:
// application.js
window.App = Ember.Application.create();
App.ApplicationAdapter = DS.FixtureAdapter.extend();
// router.js
App.Router.map(function() {
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return this.store.find('dictionary', 0);
}
});
// dictionary_model.js
App.Dictionary = DS.Model.extend({
title: DS.attr("string")
});
App.Dictionary.FIXTURES = [
{
id: 0,
title: "Hello Ember"
}];
// dictionary_controller.js
App.DictionaryController = Ember.ObjectController.extend({
});
I'm not sure where you're reading in the documentation that's contradicting, please update your question with the contradicting statements so they can be fixed.
The controller really only need be defined if you need to add additional computed properties, actions, or other methods. In your case you are correct in that it needn't be defined.
That being said, the application template (or unnamed template as in your case) is the root of your ember app. Any child routes/resources will be rendered in the {{outlet}} located in the application template(examples below).
The index route is a route underneath the application route. Resources are considered routes that can have children and generally associated with a model.
All this comes up to the main problem you're seeing. You've returned your model from the index route, but you are attempting to use it in the application route's template.
Here's a simplified version of your code
Code
App = Ember.Application.create();
App.ApplicationAdapter= DS.FixtureAdapter;
App.IndexRoute = Ember.Route.extend({
model: function() {
return this.store.find('dictionary', 0);
}
});
App.Dictionary = DS.Model.extend({
title: DS.attr("string")
});
App.Dictionary.FIXTURES = [
{
id: 0,
title: "Hello Ember"
}];
Templates
<script type="text/x-handlebars">
<h2>Application Template</h2>
Here we Are in the Application Template
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<h2>Index Template</h2>
{{title}}
</script>
Example in action
http://emberjs.jsbin.com/OxIDiVU/443/edit

Handlebars error: Could not find property 'query-params' although Feature activated

I am trying to use query-params in my route / controller but the handlebars helper is causing this error:
Uncaught Error: <(subclass of Ember._MetamorphView):ember689>
Handlebars error: Could not find property 'query-params' on object
.
This error is caused by this link to helper:
{{#link-to 'betround.stats' (query-params game=id) }}
<li {{bind-attr class="isPast:small"}}> {{team1}} {{scoreT1}} : {{scoreT2}} {{team2}} (gameid: {{id}})</li>
{{/link-to }}
I have already upgraded Ember and Handlebars
DEBUG: Ember : 1.4.0-beta.4
DEBUG: Ember Data : 1.0.0-beta.4
DEBUG: Handlebars : 1.3.0
DEBUG: jQuery : 2.0.3
As well as enabled the query-params-new feature:
<script type="text/javascript">
ENV = {FEATURES: {'query-params-new': true}};
</script>
<script src="bower_components/jquery/jquery.js"></script>
<script src="bower_components/handlebars/handlebars.js"></script>
<script src="bower_components/underscore/underscore.js"></script>
<script src="bower_components/ember/ember.js"></script>
<script src="bower_components/ember-animated-outlet/ember-animated-outlet.js"></script>
<script src="bower_components/ember-data/ember-data.js"></script>
I am not sure if it is relevant but this is also my controller for the route:
GambifyApp.BetroundStatsController = Ember.ArrayController.extend({
needs: "betround",
queryParams: ['game'],
game: null,
filteredBets: function() {
var game= this.get('game');
var bets = this.get('model');
if (game) {
return articles.filterProperty('game', game);
} else {
return articles;
}
}.property('category', 'model')
});
It's a bug in that version of Ember, it's working in canary versions.
http://emberjs.jsbin.com/ucanam/3566/edit
They put in query-params-new by accident in v1.4.0-beta3, and removed it as of v1.4.0-beta4. The release version of 1.4.0 does not have this feature, as well as the beta versions of 1.5.0.
It looks like if you wanted to keep working with query-params-new, you'll either need to use the canary build (1.6.0) or revert to 1.4.0-beta3.
https://github.com/emberjs/ember.js/issues/4372#issuecomment-35175856

Ember: controller properties not available in partial views - what am I doing wrong?

See JSFiddle: http://jsfiddle.net/cyclomarc/aYmuJ/3/
I set a property in the application controller and want to display this property in a partial view. This does not seem to work. I can access the property in the template itself, but not in the partial view rendered within the template ..
index.html
<script type="text/x-handlebars">
<h3>Ember access to controller properties</h3>
{{#linkTo 'about'}}About{{/linkTo}} <br><br>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="about">
Access to property in index template: <br>
<b>{{controllers.application.applicationVersion}}</b>
<br><br>
{{render "_footer"}}
</script>
<script type="text/x-handlebars" data-template-name="_footer">
Footer text (partial view) with a controller property:<br>
<b>{{controllers.application.applicationVersion}} MISSING</b>
</script>
app.js
var App = Ember.Application.create({});
App.Router.map(function () {
this.resource('about', { path: "/about" });
});
App.IndexRoute = Ember.Route.extend({
redirect: function () {
this.transitionTo('about');
}
});
App.ApplicationController = Ember.Controller.extend({
//Set some properties
applicationVersion: "1.0.0"
});
App.AboutController = Ember.Controller.extend({
needs: "application"
});
render view helper have your own context.
To use the current context in a other template use the partial view helper.
{{partial "footer"}}
When you use render a new controller is created, in that case named generated _footer controller.
Using partial will preserve the controller bound to the template that called the partial template
And since you used needs in about controller, you don't have it in the new generated controller.
Here is a sample