Ember. Live uploading templates - templates

I want uploading ember templates from server.
I seen for that need used like:
$.ajax({
url: 'url_to_template_text',
dataType: 'text',
success: function (resp) {
App.AboutView = Ember.View.extend({
template: Ember.Handlebars.compile(resp)
});
}
});
but i cant understand how rendering this view on page.
App.AboutView.append() - is not worked
if add routing for that view, then do not have time to render getting template:
<script type="text/x-handlebars" >
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="about">
That text cant be show
</script>
//////JS
$.ajax({
url: 'url_to_template_text',
dataType: 'text',
success: function (resp) {
App.AboutView = Ember.View.extend({
templateName: 'about',
template: Ember.Handlebars.compile(resp)
});
}
});
App.Router.map(function() {
this.route("about", { path: "/" });
});
Not worked too. Is rendering oldest template content(i mean "That text cant be show")
Please help me, perhaps i used bad way?

You can use the beforeModel hook to load the template alongside the model hook. In this case it appears you also want to use it to resolve as the default view for the route. You can do this using the Ember conventions, AboutRoute -> AboutView -> AboutController, etc.
beforeModel: function() {
return $.ajax({
url: '/about.hbs'
})
.then(function(response) {
Em.TEMPLATES.about = Em.Handlebars.compile(response);
});
},
After you load the template you need to assign it to the global Ember.TEMPLATES object.
Another approach, is to do the same for a view's template. By reopening the View's class and adding the loaded template as you do above. Note, you still have to use the view inside your handlebars template with {{view App.MyView}}.
Here's a jsbin example.

Related

How to debug a missing view

From my router, I'm rendering a view:
App.MonthSummaryRoute = Ember.Route.extend({
events: {
selectTab: function(name) {
this.render(name, { into: 'month/summary', outlet: 'tab' });
}
}
});
As an example, name is "summaryCompany". If I add a
<script type="text/x-handlebars" data-template-name="summaryCompany">
<h2>Test template</h2>
</script>
this template displays. But I tried to add a view to handle the events:
App.SummaryCompanyView = Ember.View.extend({
didInsertElement: function() {
console.log('here');
}
});
and I'm not getting anything. What am I missing?
Could you provide your entire code selection, or a JSBin / JSFiddle?
Possible approaches:
What's in your month/summary template / route / view?
Maybe you can't call render from an event. What happens when instead of doing the render from inside selectTab you do it from the route's renderTemplate hook?
renderTemplate: function() { this.render("summaryCompanyView", { into: 'month/summary', outlet: 'tab' }); }
You can try seeing if the view is inserted at all: in web inspector, find the ember-id of the div corresponding to view (somethign like <div id="ember310" ...>, then access the actual view object via Ember.Views.views.ember310 (or whatever id). You can check the view's class and see if it's App.SummaryCompanyView or a generic Ember.View
Lastly, what happens if you remove the inlined-template and specify the template on the View object via templateName?

Binding model to template with emberjs

I am going to bind model to template with emberjs
<script type="text/x-handlebars" id="dashboard">
<div>
<span>this is user list</span>
<div>
{{render userinfo userinfo}}
</div>
</div>
</script>
<script type="text/x-handlebars" id="_userinfo">
{{#each model}}
<span>{{user}}
{{/each}}
</script>
App.Userinfo= DS.Model.extend({
user: DS.attr("string")
});
App.Userinfo.FIXTURES = [
{user:"user1"},
{user:"user2"},
{user:"user3"}
];
App.UserinfoView= Ember.View.extend({
});
App.UserinfoController = Ember.ObjectController.extend({
});
App.Router.map(function() {
this.resource('dashboard', {path: '/dashboard'}, function() {
});
});
App.DashboardRoute = Ember.Route.extend({
renderTemplate: function() {
this.render('dashboard', { // the template to render
controller: 'dashboard' // the controller to use for the template
});
}
});
App.DashboardController = Ember.ObjectController.extend({
});
When i go to /#/dashboard, Dashboard template is loaded.
In here, I have rendered userinfo.
I'd like to bind Userinfo Model to usersinfo template so that I display all users.
Help me, please.
The short: here a working jsbin.
The long: You hade slightly to much unnecessary going on in your code, basically this does the job:
First of all you had no redirect to your dashboard route, since it's your only route (at least as far I can see from your code) we redirect directly to it after entering the index route
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('dashboard');
}
});
I've removed the DashboardController since there is nothing to be done.
Then your DashboardRoute was missing the model hook to provide actually data for your dashboard template
App.DashboardRoute = Ember.Route.extend({
model: function(){
return App.Userinfo.find();
}
});
In the router map you don't need to define a path if the URL is the same name as your template name in your case it is the same dashboard
App.Router.map(function() {
this.resource('dashboard');
});
The userinfo model was correct
App.Userinfo= DS.Model.extend({
user: DS.attr("string")
});
But your fixtures where missing the id
App.Userinfo.FIXTURES = [
{id:1, user:"user1"},
{id:2, user:"user2"},
{id:3, user:"user3"}
];
Moreover you where using the render helper with a partial template _userinfo the correct way to render a partial is this
{{partial userinfo}}
As you can see we don't pass any additional parameters to it because the data will be made available trough your model hook. The partial helper uses the context and the data provided in the template it is rendered into, in your case the dashboard template, therefore the model hook is necessary.
Hope it helps.

Iterate & print values in ember.js

I just have started ember.js. My markup code is
<script type="text/x-handlebars" data-template-name="home">
<h1>Names: </h1>
{{#each home in App.HomeController.content}}
<h1>Name: </h1>
{{home.name}}<br />
{{/each}}
</script>
and my javascript code is
App = Ember.Application.create();
App.Router.map(function() {
this.route("home", {
path: "/"
});
});
/*
* HomeController
*/
App.HomeController = Ember.ArrayController.extend({
content: [],
templateName: 'home',
init: function(){
var self = this;
$.ajax({
url: 'response.php',
dataType: 'JSON',
type: 'POST',
success: function(res){
self.set('content', res);
},
error: function(){
}
});
}
})
But it seems that i can not print name. I cannot iterate & print the name. Can any body help me.
Thanks
You only need to provide controller, never a full path (App.HomeController.content):
{{#each home in controller}}
<h1>Name: </h1>
{{home.name}}<br />
{{/each}}
The reasons for this:
When you write Ember.ArrayController.extend(), you create a class, not an instance. Ember will automatically create the instances for you.
The controller variable in a given template points to the controller of the same name as the template. In your case:
Template name: home
Controller: instance of App.HomeController
Also, there is no need to point to an ArrayController's content, as it's only a proxy , hence it is the default context for iterations.

EmberJs: render a template within a handlebars-helper into its parent element

Because I have the name of a View inside a variable I'm using a handlebars helper to get it rendered.
So, I have an object as follows (all simplified of course)
config = Ember.Object.create({ view: "MyTplView"}) ;
Next, I have the following template
<script type="text/x-handlebars" data-template-name="index">
<div id="container">
{{helperViewRenderer config}}
</div>
</script>
And the Handlebars helper
Ember.Handlebars.registerBoundHelper('helperViewRenderer', function(value, options) {
var template = App[value.view].create() ;
template.appendTo("#container") ;
}) ;
The problem is that I try to insert the template into the element with id "container", which doesn't exist at that moment. What are the possibilities to fix this. For example, is it possible to get a HTML-string from the template and return this instead ?
I have occasionally found it valuable to define a child view class inside of a parent view class instead of as a global. You can pass any path -- global or local -- to the view helper, and the current view is available as view in the current context. Thus,
App.ParentView = Ember.View.extend({
template: Ember.Handlebars.compile("The parent's child: {{view view.ChildView}}."),
ChildView: Ember.View.extend({
template: Ember.Handlebars.compile("-- child view --")
})
});
Ember tries to go the route of creating 'outlets' through the use of the new router.
If you want to use the appendTo method then obviously you have to append your template to an existing HTML element. In that way, you can't get a HTML string from a template (unless you know it is part of a parent template). However if you're not too bothered about where you're inserting your template, then you can use a straight append which will add the template to the end of the body.
I think in your case it would be better to get familiar with the router, as you seem to be wanting to render different templates inside the same main template. Therefore you can easily separate these out by using the URL as a variable, and injecting the relevant view into the outlet.
App.Router.map(function () {
this.route("index", { path: "/" });
this.route("first", { path: "/view1" });
this.route("another", { path: "/view2" });
});
App.FirstRoute = Em.Route.extend({
renderTemplate: function () {
this.render('view1', { outlet: 'main' });
}
});
App.AnotherRoute = Em.Route.extend({
renderTemplate: function () {
this.render('view2', { outlet: 'main' });
}
});
View:
<script type="text/x-handlebars" data-template-name="index">
<div id="container">
{{outlet main}}
</div>
</script>
This way you don't need any handlebars helper passing in variables and it's all neatly wrapped up in Ember conventions.

Query server for data on bind/observe

I apologize if this has a painfully obvious answer but I am both a JS and Ember noob and I am having trouble finding a solution to what I think is a common scenario. Essentially, I have a multi-page app with html/css/js front end and a java back end with an exposed REST api. I have 1 app.js file that I include in all screens and multiple controllers, some of which only apply to individual screens.
EDIT: Forgot my question. My question is how do I delay the query to my server for my user data until my controller has an observer. Since the controller is present on multiple screens (which dont all need it) I do not want to blindly query on creation of the object since it would be wasteful. For now i have a hacky way of doing it where at the end of my inline script tag of a page I call the populate method. Below is what my code currently looks like.
Section of app.js:
App = Ember.Application.create();
User = Ember.Object.extend({
username: 'empty',
fullname: 'empty user'
});
App.UserDataSource = Ember.Object.extend({
fetchMyUser: function(callback) {
$.get('ncaa/user', function(data) {
callback(User.create({
username: data.username,
fullname: data.fullname}));
});
}
});
App.userDataSource = App.UserDataSource.create();
App.UserController = Ember.Object.extend({
content: null,
populate: function() {
var controller = this;
this.get('dataSource').fetchMyUser(function(data) {
controller.set('content', data);
});
}
});
App.userController = App.UserController.create({
dataSourceBinding: Ember.Binding.oneWay('App.userDataSource')
});
Ember.run.sync();
Section of index.html
<script type="text/x-handlebars">
Welcome, {{App.userController.content.fullname}}
</script>
....other code....
<script type="text/javascript">
$(document).ready(function() {
....other code....
App.userController.populate();
});
</script>
I am pretty sure my first steps will be modifying that handlebars template to extend Ember.View but would like to know what the community believes is the best practice. Also, is it wrong for me to try and put all of this in one app.js file? It would be ok to query on creation of my controller if it was only imported on screens that required the user to display.
The answer for my question did end up being in the Ember.View. Essentially what I do is override the init function of my view which adds the call to populate the necessary controller with data. The view is that instantiated via the handlebars template so no more unnecessary calls or hacky work around. Important changes below.
Index.html:
<script type="text/x-handlebars">
{{#view App.UserNameView }}
Welcome, {{fullName}}
{{/view}}
</script>
App.js:
App.UserNameView = Em.View.extend({
init: function() {
this._super();
App.userController.populate();
},
fullNameBinding: 'App.userController.content.fullname',
userNameBinding: 'App.userController.content.username'
});