setting #each property, proper use - splitting search results with EmberJs - ember.js

Im trying to split search results into bulks of 5 so each bulk could be presented desperately.
my data:
Wacky.Video = Ember.Object.extend({
DATA: null
presenter : null
});
The presenter holds the page number on which the data should appear - e.g model[0-5] hold val. 1, model[6-10] hold val. 2 and so on...
my controller:
Wacky.SearchController = Ember.Controller.extend({
...
resPageNum: 1,
...
This property will de/increment whenever a page number will be changed (by button click).
my HTML code:
{{#each res in model}}
{{#if pagePresentor}}
<div class="results">
//DO STUFF WITH RES. OBJECT
</div>
{{/if}}
{{/each}}
finally "pagePresentor" is a property that needs to determine which bulk to present in the current iteration.
So far Iv got this:
pagePresentor: function(value){
return value.presenter == this.get('resPageNum');
}.property('resPageNum','#each.presentor')
But I guess Im using it wrong, because nothing is getting printed at all.
Could anyone please explain how to set this working or at least the base principal for what am I doing wrong here?
Thanks in advance.

pagePresentor: function(value){
return value.presenter == this.get('resPageNum');
}.property('resPageNum','#each.presentor')
Here #each.presentor is a mistake. You should specify observed property which is in the array in the following format: arrayName.#each.propertyName according to http://emberjs.com/guides/object-model/computed-properties-and-aggregate-data/. So, here the name of array which contains the objects with presentor property is missing.

Related

How to handle ember checkbox binding

I am new with ember and I have a question about checkbox binding.
Here is my js && hbs :
CompletedToday(id){
var today = new Date().toISOString().slice(0, 10);
this.get('DS').findRecord('menu',id).then((recs) => {
recs.get('completedDates').pushObject(today);
recs.save();
});
},
{{#each menu}}
{{input type="checkbox" checked=this.checkCompleteToday click=(action "CompletedToday" menu.id)}}
{{/each}}
Menu is a model has a attribute called Completed date, which is a array contains a list of dates(YYYY-MM-DD), there should be a constructor function to check if it’s completed TODAY, if it is completed, make the checkbox of that menu as checked. If not, user can check the specific checkbox I don’t know how to handle this actually, do i need to create another attribute for menu?
Any suggestion would be appreciated
First you need a computed property that returns true or false if TODAY is in the model.
you should create in your component a computed property like:
checked = computed('model', function() {
// pseudocode bellow
return (TODAY in array)
})
Now, if it is unchecked (TODAY not in array), you should be able to insert in array.
In you hbs:
{{input type="checkbox" checked=checked click=(action "CompletedToday" menu.id)}}
(you shouldn't use "this" to reference the property)
If "CompletedToday" is in your component actions, it should work.
I hope this helps

two-way binding on array does not work

I have an array of strings that I render as a list of inputs.
Then there is a way to add a new item (new input) into this list.
However when change a text in the inputs and then add a new item, all the changes that were previously made to the old inputs are gone - and also the array of strings in my controller does not change.
Here is a code:
http://ember-twiddle.com/653be725890f234931dd
how can I preserve changes that are made to the "old inputs"?
I am quite suprised by this behaviour, since in angular this is a pretty common thing to do and it works out of the box... so I guess I must be doing something terribly wrong here :(
I tested a way that solved the problem, but maybe there's a better way, but it can create a function to perform the change in the value index and the report that there was a change in the controller, sorry the English Google translation.
Template:
{{#each valueList key="#index" as |value index|}}
<div>{{input value=value change=(action 'updateItem' index)}}</div>
{{/each}}
Controller:
actions : {
updateItem : function( index ) {
this.get( 'valueList' )[ index ] = event.target.value;
this.notifyPropertyChange( 'valueList' );
},
},

EmberJS calling controller function within #each

I'm trying to call a controller function inside a #each template to check if the model is selected. This needs to receive the model for each loop iteration.
jsbin is here http://emberjs.jsbin.com/bemos/4/edit
I've tried using the following template, but adding a parameter to {{controller.selected}} results in ember throwing an exception, or not doing anything (the result seems to be different in jsbin).
{{#each model}}
<li><a hres="#" {{action "clickItem" this}}>{{label}} -- selected is {{controller.selected name}} </a></li>
{{/each}}
My function in the controller looks as follows
selected: function(id) {
var list = this.get("selectedList");
console.log("Checking sel for", id);
if(list.contains(id))
return true;
return false;
}.property("selectedList")
In the jsbin, I expect to be able to click on the "Hello 1"/"Hello 2" elements, and this should change the part of the text that says "selected is false" to true. It should also update the number of items selected in the bottom. Currently, this shows 1 item is selected (since the default is selectedList:["2"]) however "Hello 2" says "selected is false" - this should say "true".
(I should add I'm pretty new to EmberJS as have been working with ExtJS for a few years!).
Thanks
Do you really have a problem in code ? I guess no, since your bin is working fine and even clickItem is working as well. In your local environment where you are facing this issue, I think you are not using same version of handlebars and ember. Please check if you are using below,
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.3.0.js"></script>
<script src="http://builds.emberjs.com/tags/v1.6.1/ember.js"></script>
Update 1 -
Here is the bin I tried to update - http://emberjs.jsbin.com/veqoqocu/1/edit
Its not fully functioning but fixes some issue.
There are multiple problems,
You should use ArrayController for lists, redesign your example otherwise selected property will never work the way you want. Here is a good example - http://emberjs.com/guides/controllers/representing-multiple-models-with-arraycontroller/
push & pop needs to be pushObject and popObject
computer property on array works like - }.property('selectedList.[]')

Access computed property in ArrayController

With this controller:
CMS.PeopleController = Em.ArrayController.extend
orderedNames: ( ->
// Some ordering here...
).property "content.names"
...nothing appears here:
{{#each controllers.people.orderedNames}}
<p>Hello {{name}}</p>
{{/each}}
I guess that's because some binding to content, but I have no idea how to get it working... Can anybody help me?
Use #each to refer to properties on individual items in an array [as a dependent key]: content.#each.name Also, ensure your property is returning a value.

Reversing a content array

I'm storing a list of search terms in my ArrayController. I'd like the search terms to be displayed newest to oldest. By default Ember outputs them in order.
You can see my current implementation here: http://andymatthews.net/code/emberTweets/
And here's the pertinent code.
{{#each App.recentUsersArray.reverse}}
<li>
<a href="#" title="view again" {{action "searchAgain" target="App.recentUsersArray"}}>{{this}}</a>
</li>
{{/each}}
App.recentUsersArray = Em.ArrayController.create({
content: [],
reverse: function(){
return this.content.reverse();
}.property(),
});
You can see that I'm trying to reverse it using a property() method but it's not working. Am I doing something wrong?
You should always use get and set to access properties. Also if a computed property depends on other ones, you have to add these in the property declaration. The use of cacheable can be omitted in the next release of ember, see discussion. You can see a working example here.
reverse: function(){
return this.get('content').toArray().reverse();
}.property('content.#each').cacheable()
You could also use the unshiftObject method on an array and hereby circumvent creating a computed property, see http://jsfiddle.net/ez7bV/.