Dynamically load javascript inside Ember View - ember.js

Is it possible to run Javascript inside an Ember View Handlebars template? I want to run the Javascript when the template is added to the DOM.
window.App = Ember.Application.create()
App.TestView = Ember.View.create
tagName: 'div'
template: Ember.Handlebars.compile '<script>console.log("some javascript");</script><div>This is a view</div>'
App.TestView.append()

The didInsertElement function on a view is invoked when it has been added to DOM, see documentation.
You can then access the added view via this.$(), see http://jsfiddle.net/NuaA6/
Handlebars:
<script type="text/x-handlebars" data-template-name="tmpl" >
hello from template
</script>​
JavaScript:
App = Ember.Application.create({});
Ember.View.create({
templateName: 'tmpl',
didInsertElement: function() {
console.log('view has been added to dom', this.$());
}
}).append();

Related

Ember js version 1: Route hierarchy / activation

We have a scenario along these lines:
Quote
--->Create
So route names quote and quote.create.
The issue is that we need to render the templates into the main outlet. So in our main route (that all other are inherited from) we have this:
renderTemplate: function() {
this.render({ into: 'application' });
}
When I navigate to quote it renders the quote view. From there I navigate to quote.create and it renders the create view. However, going back to quote from quote.create renders nothing.
How can I get around this?
When I go back to the \quote url route 'quote.index' is sought. Since it is defined 'automagically' nothing happens. When I define the route explicitly ember tries to find the quote.index template and view and these do not exist.
A workaround I tried is to have this:
App.QuoteIndex{Route|Controller|View} = App.Quote{Route|Controller|View}.extend()
EDIT:
Hey diddle-diddle, here is my fiddle :) http://jsfiddle.net/EbenRoux/Mf5Dj/2/
Ember.js does not rerender a parent view when transitioning to a parent route, so using into with a parent view template is not recommended.
There is an easier way to create what you are trying to: use a quote/index route:
<script type="text/x-handlebars" data-template-name="application">
<h1>Rendering Issue</h1>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="quote">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="quote/index">
<h2>Quote View</h2>
{{#linkTo 'quote.create'}}Create a new quote{{/linkTo}}
</script>
<script type="text/x-handlebars" data-template-name="quote/create">
<h2>Quote Create View</h2>
<p>Some controls would go here.</p>
{{#linkTo 'quote'}}Go back to quote view{{/linkTo}}
</script>
App = Ember.Application.create({});
App.ApplicationRoute = Ember.Route.extend({
activate: function () {
this.transitionTo('quote');
}
});
App.Router.map(function () {
this.resource('quote', function () {
this.route('create');
});
});
See http://jsfiddle.net/eYYnz/

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

Accessing Ember controller attributes from a controller

I have the following controller:
App.ShowController = Ember.Controller.expend({
buttonTitle: 'Create'
});
And the following template show.handlebars
<a href='#'>{{buttonTitle}}</a>
but the text is not rendering. Is there a special call to access the attribute?
Normally, when a view is displayed (via the Router), the context of the view is automatically set to the controller, so there should be nothing to do special.
Here is an example, where the MyApp.IndexController is automatically set as the context of the IndexView (and its template is the index template):
MyApp = Ember.Application.create({});
MyApp.Router = Ember.Router.extend();
MyApp.Router.map(function(match) {
match('/').to('index');
});
MyApp.IndexController = Ember.Controller.extend({
buttonTitle: "create"
});
The template:
<script type="text/x-handlebars" data-template-name="index">
{{buttonTitle}}
</script>
And you could try it on this JSFiddle.
N.B.: I'm using Ember v1.0.0-pre.2-239 here. There are some changes to do for upgrading this example to master

why view. is needed in handlebars

I can't understand something in Ember.js, my contains a property, but in order to display it i have to do {{view.property}}, why can't I simple use {{property}} ?
in the following example only {{view.test}} is displayed.
shouldn't the view be the default scope ?
index.html:
<script type="text/x-handlebars" data-template-name="places">
{{test}} {{view.test}}
</script>
app.js:
App.PlacesController = Ember.ArrayController.extend({
});
App.PlacesView = Ember.View.extend({
templateName: 'places',
test: 'test'
});
As of Ember 1.0pre, the context for handlebars helpers in your template has been changed to be the controller.
Before that, it was the view. The view keyword is available to access properties from the view.
Try adding a test property to your controller and see what happens.

How to add css classes to a child view from handlebar template

I would like to add a css class to a child view from a handlebars template. I am currently getting an error as follows:
Uncaught TypeError: Object [object DOMWindow] has no method 'get'
My code is as follows:
App = Ember.Application.create()
App.ParentView = Ember.View.extend({
foo: 'bar',
content: 'Hello',
ChildView: Ember.View.extend({
classNames: this.get('parentView').get('classesToAdd')
})
});
I have a jsfiddle here: http://jsfiddle.net/sohara/PKMTn/2/
Is there something special about the classNames property that shifts the context from the Ember.View to a dom element? Or perhaps there's some other way that I can achieve this?
You can overwrite the init on the view to access classesToAdd, see http://jsfiddle.net/WCjda/1/
Handlebars:
<script type="text/x-handlebars">
{{#view App.ParentView}}
{{#view ChildView classesToAdd="my-class"}}
hello
{{/view}}
{{/view}}
</script>​
JavaScript:
App = Ember.Application.create()
App.ParentView = Ember.View.extend({
foo: 'bar',
content: 'Hello',
ChildView: Ember.View.extend({
init: function() {
this._super();
var classes = this.get('classesToAdd');
this.set('classNames', Ember.makeArray(classes));
}
})
});​
I don't think you can use this in your classNames declaration of your ChildView because the view object has not been instantiated.
However, you can use bindings. See the documentation at Emberjs.com under the "Customizing the HTML Element" section.