Ember- Showing models data in view - javascript

Im wondering here, how to show models data e.g Organization model>name field in ember view
I tried something like this.
organization VIEW
OrganizationObserver : function(){
var organizationModel = this.get('controller.organizations');
//this.OrganizationComputedProperty(organizationModel);
console.log(organizationModel);
}.observes('controller.organizations').on('init'),
OrganizationComputedProperty: function(){
console.log("herrro");
}.property('organization'),
Model
var Organization = DS.Model.extend({
name: DS.attr('string'),
address: DS.belongsTo('agents/address')
});
// Initial data for Organization model, only applies when using
// FixtureAdapter
Organization.FIXTURES = [
{
id: 1,
name: 'TU',
address: 1,
},
{
id: 2,
name: 'TLU',
address: 2,
}
];
Main hbs
{{#each personFormCount}}
{{view 'organization'}}
{{/each}}
Controller
personFormCount: [{id: 1}, {id: 2}]
But i know that's wrong, because they watch for change behaviours which don't take place in model..
Cheers,
Kristjan

Since i was capable of getting model to my view by this.get('controller.organizations')
Which is defined in route
controller.set('organizations', this.store.findAll('agents/organization'));
I looked at the select once again
{{view Ember.Select
contentBinding="organizations"
optionValuePath="content.id"
optionLabelPath="content.name"
selectionBinding="selectedAgent"
class="form-control"
}}
And i just added controller.organizations to contentBinding
{{view Ember.Select
contentBinding="controller.organizations"
optionValuePath="content.id"
optionLabelPath="content.name"
selectionBinding="view.selectedAgent"
class="form-control"
}}

Related

accessing collection inside json object angular

I am new to angular
in the following controller i need to access the object store in my html. But it is not working. Any help
(function () {
'use strict';
angular.module('app').controller('BookController', ['$scope', function ($scope) {
$scope.book = {
id: 1,
name: 'Harry Potter',
author: 'J. K. Rowling',
stores: [
{ id: 1, name: 'Barnes & Noble', quantity: 3 },
{ id: 2, name: 'Waterstones', quantity: 2 },
{ id: 3, name: 'Book Depository', quantity: 5 }
]
};
}]);
});
<div ng-controller="BookController">
{{book.stores}}
</div>
You need to first invoke your anonymous function first using () after the final closing bracket and before the final semi-colon so that the last line looks like this: })();.
You should define angular module first and then amend it with the angular component like controller, service , factory, directive, filters, etc.
angular.module('app', [])
then add ng-app="app" on your page.
Markup
<div ng-app="app" ng-controller="BookController">
{{book.stores}}
</div>
Plunkr Here
Update
If suppose you have multiple store inside the stores object, and you want to show them on the html, then for that you could ng-repeat directive. It will repeat each element on html
<div ng-repeat="s in book.stores">
<span>{{s.name}}</span>
<input type="text" ng-model="s.name" />
<input type="numeric" ng-model="s.quantity" />
</div>
Updated Plunkr

ember {{input}} helper not working

I can't for the life of me figure out why this won't work. Maybe it's obvious, but I've been staring at it too long.
I want the {{input}} pre-populated with the value of Title, the label gets filled in correctly...
<ul>
{{#each}}
<li>
{{input type="text" value=Title }}
<label>{{Title}}</label>
</li>
{{/each}}
</ul>
here's a Gist
Here's the javascript:
window.App = Ember.Application.create({
LOG_TRANSITIONS: true
});
App.ApplicationAdapter = DS.FixtureAdapter.extend();
App.Router.map(function () {
this.resource('Kids', { path: '/' });
});
App.KidsRoute = Ember.Route.extend({
model: function () {
return this.store.find('Kid');
}
});
App.Kid = DS.Model.extend({
Title: DS.attr('string'),
Age: DS.attr('number')
});
App.Kid.FIXTURES = [
{
id: 0,
Age: 5,
Title: "Joe"
},
{
id: 1,
Age: 9,
Title: "Max"
}
];
There seems to be a little bug with {{input}}. The problem was that title is capitalized. I got it to work in this bin. I would recommend to start your attribute names always with a small letter. This is some kind of convention. Most often you will encounter this style opposed to yours.
These are the changes i made to get it to work:
1 - add an alias to title, which is not capitalized:
App.Kid = DS.Model.extend({
Title: DS.attr('string'),
Age: DS.attr('number'),
title : Ember.computed.alias("Title")
});
2 - use the uncapitalited version with the helper:
{{input type="text" value=title }}

Populate checkbox values with model data in Ember.js

I have an ember application which has a number of users. Each of these users can be associated with a number of subjects. So I have a subjects model:
App.Subjects = DS.Model.extend({
subject : DS.attr('string'),
});
App.Subject.FIXTURES = [{
id: 1,
name: 'Sales',
}, {
id: 2,
name: 'Marketing',
}
];
and a users model:
App.User = DS.Model.extend({
name : DS.attr(),
email : DS.attr(),
subjects : DS.hasMany('subject'),
});
App.User.FIXTURES = [{
id: 1,
name: 'Jane Smith',
email: 'janesmith#thesmiths.com',
subjects: ["1", "2"]
}, {
id: 2,
name: 'John Dorian',
email: 'jd#sacredheart.com',
subjects: ["1", "2"]
}
];
I am having trouble representing this 1:M relationship in my templates. I have an edit user template (which Im also using to create a user) in which you can select the user's subjects via checkboxes. However, I want these checkboxes to be driven by the data in my subjects model. Is this possible? I have found very little documentation online and am very new to ember development. Here is my template:
<script type = "text/x-handlebars" id = "user/edit">
<div class="input-group">
<div class="user-edit">
<h5>User name</h5>
{{input value=name}}
<h5>User email</h5>
{{input value=email}}
<h5>Subjects</h5>
{{input type="checkbox" value = "sales" name="sales" checked=sales}}
{{input type="checkbox" value = "support" name="support" checked=support}}
</div>
<button {{action "save"}}> Save </button>
</div>
</script>
EDIT: Here is my current userController.js
App.UserController = Ember.ObjectController.extend({
deleteMode: false,
actions: {
delete: function(){
this.toggleProperty('deleteMode');
},
cancelDelete: function(){
this.set('deleteMode', false);
},
confirmDelete: function(){
// this tells Ember-Data to delete the current user
this.get('model').deleteRecord();
this.get('model').save();
// and then go to the users route
this.transitionToRoute('users');
// set deleteMode back to false
this.set('deleteMode', false);
},
// the edit method remains the same
edit: function(){
this.transitionToRoute('user.edit');
}
}
});
what you need to do is change this line in your template:
{{#each subject in user.subject}}
{{subject.name}},
{{/each}}
for this:
{{#each subject in user.subjects}}
{{subject.name}},
{{/each}}
did you notice I changed subject for subjects ?
and, I would also recommend you to change this code in App.SubjectController:
selected: function() {
var user = this.get('content');
var subject = this.get('parentController.subjects');
return subject.contains(user);
}.property()
to this:
selected: function() {
var subject = this.get('content');
var userSubjects = this.get('parentController.subjects');
return userSubjects.contains(subject);
}.property()
that's a better representation of the data.

How do I loop through each record in my data model in a template?

I have a model setup with Ember fixtures. My model is like the following:
App.Question = DS.Model.extend({
isCompleted: DS.attr('boolean'),
question_top: DS.attr('string'),
question_bottom: DS.attr('string'),
etc......
});
My fixtures (the actual data) is like the following:
App.Question.FIXTURES = [
{
id: 1
},
{
id: 2
}
];
I want to create a unordered list in my template that shows a "li" item for each record in my Fixtures. I think I need to use the {{#each question}} syntax but when I do {{#each question}}, it doesn't work.
How do I loop through my Fixtures data to create a unordered list, with one list item for each record in my Fixtures data?
Probably your question property doesn't exist in your controller. If you are doing:
App.QuestionRoute = Ember.Route.extend({
model: function() {
return this.store.find('question');
}
});
You can use:
<h2>Questions:</h2>
<ul>
{{#each model}}
<li>{{question_top}}</li>
{{/each}}
</ul>
Give a look in that fiddle http://jsfiddle.net/marciojunior/25GHN/
You need to return it to a route's model hook:
http://emberjs.jsbin.com/UGEmEXEy/1/edit
App.IndexRoute = Ember.Route.extend({
model: function() {
return this.store.find('question');
}
});
App.QuestionAdapter = DS.FixtureAdapter;
App.Question = DS.Model.extend({
isCompleted: DS.attr('boolean'),
question_top: DS.attr('string'),
question_bottom: DS.attr('string')
});
App.Question.FIXTURES = [
{
id: 1,
isCompleted: true
},
{
id: 2,
isCompleted: false
}
];

Link to nested resource loses active class after page reload

I'm learning ember these days and I encountered a problem with link-to helper. If I use it to create a link for nested route it works fine (if click on the link, "active" class will be added to the element - as described in docs) until I reload the page. When I reload the page the content for nested rouse will be loaded to the {{outlet}} properly but link will lose its "active" class. What am I doing wrong?
JavaScript:
window.App = Ember.Application.create({ rootElement: '#app' });
App.Router.map(function () {
this.resource('notes', { path: '/' }, function () {
this.route('show', { path: '/:note_id' });
});
});
App.NotesRoute = Em.Route.extend({
model: function () {
return App.Note.find();
}
});
App.NotesShowRoute = Em.Route.extend({
model: function (params) {
return App.Note.find(params.note_id);
}
});
App.Note = Em.Object.extend();
App.Note.reopenClass({
find: function(id) {
var notes = [
{
id: 1,
title: 'abc',
text: 'lorem ipsum text 1111111'
},
{
id: 2,
title: 'def',
text: 'lorem ipsum text 2222222'
}
];
return id ? notes[parseInt(id) - 1] : notes;
}
});
HTML:
<div id="app" class="row">
<script type="text/x-handlebars">
<div class="col-md-2">
<h2>Tags</h2>
</div>
{{outlet}}
</script>
</div>
<script type="text/x-handlebars" data-template-name="notes">
<div class="col-md-3">
<h2>Notes</h2>
{{#each}}
{{#link-to 'notes.show' this}}{{title}}{{/link-to}}
{{/each}}
</div>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="notes/show">
<div class="col-md-7">
<h2>{{title}}</h2>
<p>{{text}}</p>
</div>
</script>
When you click a link-to, it passes the object to the new route. So the model lookup isn't called. So both the context of the show route and the linked object refer to the same object. So it will get marked as active.
However, when you refresh the page, you're doing the lookup twice, once in the NotesRoute model (which you loop over with each), and once in the NotesShowRoute model.
Javascript objects are reference types. Two plain javascript objects aren't considered equal, even if their content is the same. e.g. try typing this into your javascript console.
{ one: 1, two: 2} == {one: 1, two: 2}
So the object referred to in the link-to isn't the same as the model of the current route. So the equality check for the link being active won't work.
Quick solution is to stop the find from creating the object every time. e.g.
App.Note.reopenClass({
all: [
{
id: 1,
title: 'abc',
text: 'lorem ipsum text 1111111'
},
{
id: 2,
title: 'def',
text: 'lorem ipsum text 2222222'
}
],
find: function(id) {
return id ? this.all[parseInt(id) - 1] : this.all;
}
});
Another options is to roll some sort of identity map for your objects. Here is a blog post doing a much better example than I can of explaining it.
Note I haven't actually tested that code because I'm too lazy to create a jsbin. But let me know if it doesn't work.

Categories

Resources