How to push an object into a one dimensional array and how to get individual item in array using ember.js - ember.js

Here is my code, I want to get userData details it is in the form of array,so i push that object into results array, am getting userData items into my result array but i can't access the individual item ,and that i want to display in my template using {{#each}}{{/each}}, help me to find this.
enter code here
addSuccess: function(userData) {
Ember.Logger.log('user address data',userData);
var results = [];
results.push(userData);
this.set('result',results);
Ember.Logger.log('result data result',this.get('result.addresses.city'));
this.send('btnClose');
}

If I understand your question correctly, userdata is a plain object. Since Ember 2.1 you could iterate over an object with the each-in helper. So your code would look something like:
Controller/Route
addSuccess: function(userData) {
this.set('controller.userData', userData);
}
Template
<ul>
{{#each-in userData as |key value|}}
<li>{{key}}: {{value}}</li>
{{/each-in}}
</ul>

Related

Each bound to array displays only the first item

I am building an Ember App. I have the following in my template :
{{#if App.selected}}
<p class="small-desc">{{App.selCount}} product added to list</p>
{{#each App.selected}}
{{button-custom action="removeFromList" params=this close="true" class="col-xs-12" text=this}}
{{/each}}
{{button-custom action="proceedToDetails" class="col-xs-12" color="red" text="Next"}}
{{/if}}
Here App.selected is an Array []. When a product is selected, it is added to the Array. At the first click, the item(selected) is added and is displayed on the browser. When the next product is clicked, there is no visible change in the browser. But using the console I have checked and ensured that the new product was added to App.selected. But Ember displays only the first one.
Due to the very odd nature of this problem and fruitless searches made on Google, I am posting this as a question here.
Additional info -
NOTE: App is not the Ember application. It's just a variable
I populate App.selected as :
a = App.selected;
a.push('name');
Ember.set(App, 'selected', a);
button-custom is a component that uses 'text' as its caption.
If I visit the same route without reloading(after selecting more than 1 products), all the items in the array are displayed correctly.
Other {{#each}}'s that are bound to different arrays on the same page work as they should.
I tested the #each block on other routes too. Everywhere its the same. I replaced button-custom with plain text 'asd' and it exhibits the same behavior. (My intuition tells me I have made some mistake, a very silly one!)
The array is declared as :
App = {
selected : null
}
The controller for this template is an ObjectController. Initially, #each was bound to selected property of the controller. But when that didn't work, I bound it to an array in namespace App. The results were the same, then and now.
UPDATE
It seems that each will not always iterate over an array. Suppose an #each block over variable Arr. If Arr is null, #each displays nothing. When you set Arr to any array(empty or populated), then Ember renders the contents of Arr. But this happens only the first time. The next time you set Arr to another array, Ember will not repopulate #each, unless you set it to null.
Ember does not guarantee best results with a JS array. So I had to change my array to Ember Mutable Array :
App.Search = {
selected = Ember.A([]);
}
And then, as #blessenm suggested, add to the array with pushObject :
a = App.Search.selected;
a.pushObject('product');
Ember.set(App.Search, 'selected', a);
To remove from array :
a = App.Search.selected;
a.removeObject('product');
Ember.set(App.Search, 'selected', a);

Dynamically create view

I'm generating a list of views that the client should cycle through on the server. The server returns a list of something like 'App.AView', 'App.BView', 'App.CView", ..., etc. that refer to views and templates on the client.
I'd like to dynamically create these views, swap out the previous view, and include the new view. My first though was to compile a handlebars template with this dynamic view name, ala:
App.QuestionView = Em.View.extend({
template: function() {
return Ember.Handlebars.compile("{{view " + this.get("view_name') + "}}");
}
});
Which works, but seems ugly - is there a way to create a view with a string of the view name in Ember.JS and replace an existing view in a parent view with that view?
You want to look at Ember.ContainerView, which will let you programmatically manage a set of child views. Container View's documentation is excellent, check out: http://emberjs.com/api/classes/Ember.ContainerView.html
Since it sounds like you only ever want one view displayed at a time you can focus on the currentView property, which will automatically maintain your childViews array for displaying a single view.
Also here is an example: http://www.emberplay.com/#/workspace/2792969430

Ember Handlebars Embed ID

I am trying to use ember to show a dynamic list of found content. The problem is that when I try to put handlebars in html attributes, everything breaks.
RegApp.PatronsFound = Ember.CollectionView.create
tagName: 'table'
content: []
itemViewClass: Ember.View.extend
template: Ember.Handlebars.compile("<td><button onclick='alert({{content.id}})'>{{content.name}}</button>")
RegApp.PatronsFound.appendTo('body')
When it is fed a piece of content with the ID of 3 and the name FOO, I want this html to be generated:
<button onclick="alert(3)">FOO</button>
Instead, I get this:
<button onclick="alert(<script id=" metamorph-4-start'="" type="text/x-placeholder">3<script id="metamorph-4-end" type="text/x-placeholder"></script>)'>FOO</button>
You can use
{{unbound content.id}}
to arbitrarily insert values into your templates. Normally, such values are wrapped in metamorph tags which allow the displayed value to be bound to the backing value, and updated whenever the backing value changes. This only works if the output is regular HTML, not, in this case, spanning event handlers and embedded JS. {{unbound}} inserts the value at that property path once, without metamorph tags, and without being updated if that value changes in the future.

Ember Data: Proper Way to Use findAll

I am trying to use ember-data using https://github.com/emberjs/data as a reference.
Specifically, I am trying to use an array controller to display all of the 'Person' objects in my database. I also want to allow the user to create a new 'Person'.
I have the following code which works:
App.peopleController = Em.ArrayController.create
content: App.store.findAll(App.Person)
newPerson: (name) ->
App.store.create App.Person,
name: name
#set('content', App.store.findAll(App.Annotation))
However, it seems inefficient to reset the content property every time a new person is created. If I remove the last line and change the code to the following:
App.peopleController = Em.ArrayController.create
content: App.store.findAll(App.Person)
newPerson: (name) ->
App.store.create App.Person,
name: name
A new view is still created on ever newPerson call, but the same object is duplicated. Essentially what is happening is all of the new templates use the first object created instead of a new one each time. I think this is related to the following bug: https://github.com/emberjs/data/issues/11.
For reference, my template logic is as follows:
{{#each App.peopleController}}
{{#view App.PersonView contentBinding="this"}}
{{#with content}}
Client id is {{clientId}}
{{/with}}
{{/view}}
{{/each}}
When I use the second version of my code-- the one with the #set('content', App.store.findAll(App.Annotation)) line-- the clientId is duplicated for every Person object. In the first version, the client ids are correct.
Can anyone shed some light here? Am I doing this correctly? My instincts are telling me this is a bug but I am not sure.
I think it is a bug. I posted a related issue that illustrates this issue.
Try using the #collection view instead.
See code of ToDo example. Also see http://guides.sproutcore20.com/using_handlebars.html section 5 for some documentation.
Hope this helps.

How To I Replace New Elements Added To A Page With Jquery

Here is the scenario... I have a a checkbox next to each field that I am replacing on page load with jquery with "Delete" text that enables me to delete the field via jquery, which is working fine. Like so...
$(".profile-status-box").each(function(){ $(this).replaceWith('<span class="delete">' + 'Delete' + '</span>') });
The problem comes in however is that after page load, I am also giving the user the option to dynamically add new fields. The new added fields though have the checkbox and not the delete link because they are not being replaced by jquery since they are being added after the initial page load.
Is't possible to replace the content of new elements added to the page without doing a page refresh? If not, I can always have two templates with different markup depending one for js and one for non js, but I was trying to avoind taht.
Thanks in advance.
You can use the .livequery() plugin, like this:
$(".profile-status-box").livequery(function(){
$(this).replaceWith('<span class="delete">Delete</span>')
});
The anonymous function is run against every element found, and each new element matching the selector as they're added.
Have a look at this kool demo. It removes and adds elements like a charm.
http://www.dustindiaz.com/basement/addRemoveChild.html
Here's how:
First of all, the (x)html is real simple.
xHTML Snippet
<input type="hidden" value="0" id="theValue" />
<p>Add Some Elements</p>
<div id="myDiv"> </div>
The hidden input element simply gives you a chance to dynamically call a number you could start with. This, for instance could be set with PHP or ASP. The onclick event handler is used to call the function. Lastly, the div element is set and ready to receive some children appended unto itself (gosh that sounds wierd).
Mkay, so far so easy. Now the JS functions.
addElement JavaScript Function
function addElement() {
var ni = document.getElementById('myDiv');
var numi = document.getElementById('theValue');
var num = (document.getElementById('theValue').value -1)+ 2;
numi.value = num;
var newdiv = document.createElement('div');
var divIdName = 'my'+num+'Div';
newdiv.setAttribute('id',divIdName);
newdiv.innerHTML = 'Element Number '+num+' has been added! <a href=\'#\' onclick=\'removeElement('+divIdName+')\'>Remove the div "'+divIdName+'"</a>';
ni.appendChild(newdiv);
}
And if you want to,
removeElement JavaScript Function
function removeElement(divNum) {
var d = document.getElementById('myDiv');
var olddiv = document.getElementById(divNum);
d.removeChild(olddiv);
}
and thats that. bobs your uncle.
This is taken from this article/tutorial: http://www.dustindiaz.com/add-and-remove-html-elements-dynamically-with-javascript/
I've just learnt this myself. thank you for the question
Hope that helps.
PK