Nested loops: Access object from parent view - ember.js

I've got basically two arrays of objects in one view:
App.List = Ember.View.extend({
students: [{ "name": "yehuda" }, { "name": "tom" }],
teacher: [{ "name": "mr. katz" }, { "name": "mr. dale" }]
});
My handlebars look something like this:
{{#each teacher}}
<li class="teacher">{{name}}</li>
{{#each students}}
// display students for this teacher
{{/each}}
}}
The obvious problem here is, that the students-array is not within the teacher-array but on the same "level". So how can I access the students-array?
Thanks!

It seems to be related to the view context, try to use {{view.students}}, I think it should work.
jsfiddle updated against comments: http://jsfiddle.net/Sly7/gdXfN/

Related

Vuejs, removing element from nested lists

This is a followup question on VUEJS remove Element From Lists?, where they give various methods (this.$remove, splice, this.$delete) for dynamically removing a element from a list. I was trying to understand how to apply this to a nested loop; here's mine in three+ levels, somewhat stripped-down:
<template v-for="(labtype,index) in labIRlist">
<template v-for="(lab,index2) in labtype">
<tr v-for="(IR,index3) in lab.irs" :key="IR.irn">
<td><p>{{ lab.hidtxt }}_{{ lab.mnem }}</p></td>
<td><p>{{ lab.PNL }}</p></td>
<td><p>{{ IR.provider}} {{ IR.psurv }}</p></td>
<td><p>{{ IR.year }}-{{ IR.eventno }}</p></td>
<td><p>{{ IR.analytes }}</p></td>
<td><p>
<button type="button"
#click="deleteIR(IR.irn,index,index2,index3)">
DELETE
</button>
</p></td>
</tr>
</template>
</template>
Then there's Javascript for the deletion
methods: {
deleteIR: function(IRNum,index,index2,index3) {
// okay, delete!
//... code to do something at the database...
alert('IR successfully deleted!')
// don't show the deleted IR any more
this.labIRlist[index][index2].irs.splice(index3,1);
},
Awful, but I didn't know how to identify the correct element. And it still didn't work (AFAIK it does nothing, no change visible to the row). How should this be done - don't we know the right element from where deleteIR was called?
What is the better way to handle deleting an element within multiple
loops?
First of all, looking at how your template is built, we can assume that your data looks something like this:
labIRlist: [
[
{
hidtxt: "TEXT 1",
irs: [{ provider: "provider1" }, { provider: "provider11" }],
irn: "irn1",
},
{
hidtxt: "TEXT 2",
irs: [
{ provider: "provider2" },
{ provider: "provider22" },
{ provider: "provider222" },
],
irn: "irn2",
},
],
[
{
hidtxt: "TEXT 3",
irs: [{ provider: "provider3" }],
irn: "irn3",
},
],
],
If you want to delete one item from the nested irs array, all you need to do is to pass the irs array and the index of the item you want to delete, no need to do the whole path you are doing currently:
this.labIRlist[index][index2].irs.splice(index3,1);
So change your template to:
<button type="button" #click="deleteIR(lab.irs, index3)">
And the delete function is then simply:
deleteIR(IRS, index) {
IRS.splice(index, 1);
}
A DEMO for your reference
PS. Please always share a bit of your data when posting questions like this. Much easier to answer when not needing to create your own sample data like I did here.

Dust.js context issue?

I have the following partial:
<ul class="navbar">
{#nav_links}
<li class="navbar__link {?sub_menu}more{/sub_menu}">
{label}
{?sub_menu}
<ul class="navbar__link--sub">
{#sub_menu}
<li class="navbar__link--sub {?sub_menu}more{/sub_menu}">
{label}
</li>
{/sub_menu}
</ul>
{/sub_menu}
</li>
{/nav_links}
</ul>
With JSON:
{
title: "page title",
nav_links: [
{
link: "home",
label:"Home"
},
{
link: "products",
label:"Products",
sub_menu: [
{link: "link1", label: "Product A"},
{link: "link2", label: "Product B"},
{link: "link3", label: "Products C", sub_menu: [
{link: "link3-1", label: "Sub Product A"},
{link: "link3-2", label: "Sub Product B"}
]},
]
}
]
}
The issue I've run into is the nested sub_menu property, all sub menu items add the more class regardless if they have a nested sub_menu or not. I thought the context would have shifted like it does with link and label, however it seems to still refer to the initial sub_menu like the first conditional and section tags do. I've renamed the nested sub_menu property in the JSON and partial tag, context works correctly then. Is there a way to still use the sub_menu property name? Or reference the child property such as sub_menu.sub_menu?
By default, Dust will walk up the context if it doesn't find a key at a certain level. However, you're wanting to explicitly check only the current level of the context. To do this in Dust, prefix the key with a dot:
<li class="navbar__link--sub {?.sub_menu}more{/sub_menu}">

EmberJS RESTAdapter not populating model using ember-data

I am trying to use the ember-data to build a model from a my own REST service. I have formatted my data according to how I understand the data should be returned from the service, but still stuck.
The issue is that I get no results showing in my view after initial page load. I dont think the model is being populated correctly.
What am I missing?
App = Ember.Application.create();
App.Account = DS.Model.extend({
first: DS.attr( 'string' ),
last: DS.attr( 'string' )
});
App.AccountAdapter = DS.RESTAdapter.extend({
namespace: 'api',
host: 'http://127.0.0.1:3000'
});
App.Router.map(function() {
this.route('home');
});
App.HomeRoute = Ember.Route.extend({
model: function() {
return this.store.find( 'account' );
}
});
App.HomeController = Ember.Controller.extend({
controllerTest : true
});
My data looks like the following:
{
"accounts": {
"id": 1,
"first": "John",
"last": "Doe"
}
}
from url:
http://127.0.0.1:3000/api/accounts
My view template is:
<script type="text/x-handlebars" data-template-name="home">
Home Template {{controllerTest}}
{{#each item in model}}
<br />
{{item.first}}
{{item.last}}
{{/each}}
</script>
Thanks.
I think your JSON format is slightly incorrect. It is my understanding you return a list of accounts, even if there's only one. Try this:
{
"accounts": [
{
"id": 1,
"first": "John",
"last": "Doe"
}
]
}
Try
{{#each }}
<br />
{{first}}
{{last}}
{{/each}}
or
{{log this}}
or use Ember-inspector to see what data do you have and whats going on there.

how to get kendoui grid popup add/edit form created from kendo template, show the correct title for add and edit operations?

I can't seem to find a simple way to set the title on a popup add and edit form launched from the kendoui grid, when it is created using a custom template. When I tried the following example, both Add and Edit operations had "Edit" in the title bar of the popup:
Markup:
<script id="popup-editor" type="text/x-kendo-template">
<p>
<label>Name:<input name="name" /></label>
</p>
<p>
<label>Age: <input data-role="numerictextbox" name="age" /></label>
</p>
</script>
<div id="grid"></div>
JavaScript:
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{ field: "age" },
{ command: "edit" }
],
dataSource: {
data: [
{ id: 1, name: "Jane Doe", age: 30 },
{ id: 2, name: "John Doe", age: 33 }
],
schema: {
model: { id: "id" }
}
},
editable: {
mode: "popup",
template: kendo.template($("#popup-editor").html())
},
toolbar: [{ name: 'create', text: 'Add' }]
});
Fiddle demonstrating the issue: http://jsfiddle.net/codeowl/XN5rM/1/
The issue is that when you press the Add or Edit buttons, the title bar in the popup says: "Edit". I want it to say Add when you press the Add button and Edit when you press the Edit button.
Thank you for your time,
Regards,
Scott
If you want a simple solution, add code to the edit event of the grid to check to see if the model being created when edit is called is a new one or an existing one and set the text accordingly:
...
edit: function (e) {
//add a title
if (e.model.isNew()) {
$(".k-window-title").text("Add");
} else {
$(".k-window-title").text("Edit");
}
}
...
Hope this helps...
If the only thing that you need to do is add a title, you should use:
editable : {
mode : "popup",
window : {
title: "Edición",
}
},
You don't need to define a template unless you need to define something else.
Your modified Fiddle here : http://jsfiddle.net/OnaBai/XN5rM/2/

Ember.js - Code is working with 0.9.5 but not 1.0.pre

I try to figure out why the following fiddle doesn't work with ember.js 1.0.pre while 0.9.5 works.
Version 0.9.5 (working)
http://jsfiddle.net/tPfNQ/1/
Version 1.0.pre (not working)
http://jsfiddle.net/hSzrZ/1/
I know that handlebars.js is not included in the latest build of ember.js and i have to include it by my own.
Here is the code i'm using:
<script type="text/x-handlebars">
{{#view Ember.Button target="Welcome.booksController" action="loadBooks"}}
Load Books
{{/view}}
{{#collection contentBinding="Welcome.booksController"}}
<i>Genre: {{content.genre}}</i>
{{/collection}}
</script>
Welcome = Ember.Application.create();
Welcome.Book = Ember.Object.extend({
title: '',
author: '',
genre: ''
});
var data = [ { "title": "Ready Player One", "author": "Ernest Cline", "genre": "Science Fiction" }, { "title": "Starship Troopers", "author": "Robert Heinlein", "genre": "Science Fiction" }, { "title": "Delivering Happiness", "author": "Tony Hsieh", "genre": "Business" } ];
Welcome.booksController = Ember.ArrayController.create({
content: [],
loadBooks: function(){
var self = this;
data.forEach(function(item){
self.pushObject(Welcome.Book.create(item));
});
}
});​
Source is: http://www.andymatthews.net/read/2012/03/07/Getting-Started-With-EmberJS
This is the most common issue people have with upgrading to 1.0.
The default view context has now changed to be the context of the view rather than the view itself.
So to access a value from the view's content you need to specify it via view.content.xxx.
{{#collection contentBinding="Welcome.booksController"}}
<i>Genre: {{view.content.genre}}</i>
{{/collection}}
In this particular case you could also use the #each helper if you wanted.
{{#each Welcome.booksController}}
<i>Genre: {{genre}}</i>
{{/each}}
I think there is talk of changing the #collection helper to work similarly.