I'm trying to render out a list of items and provide select inputs for each item. The options for select come from the store, so would be a promise when passed to the Ember.Select. Is this possible? It doesn't look like the view will rerender if the content changes, so it seems like I might have to do that.
My template (abbreviated)
{{#each fruitBins}}
<tr>
<td>{{id}}</td>
<td> {{view Ember.Select
content=fruitTypes
optionLabelPath="content.name"
optionValuePath="content.id"
prompt="Select a Fruit Type"
}}
</td>
</tr>
{{/each}}
fruit_bins_controller.js:
...
fruitTypes: function () {
return this.store.find('fruitType');
}.property(),
The only thing that appears when the select is rendered is the prompt.
Ember: 1.3.1, Data: 1.0.0.beta4
Turns out I was wrong understanding my issue.
Made the updates as #edpaez suggested, which I think aligns my code with conventions. I added the following to my route:
model: function () {
return Em.RSVP.hash({
content: this.modelFor('<the parent element>'),
fruitTypes: this.store.find('fruitType')
});
},
setupController: function(controller, model) {
controller.setProperties(model);
}
I still had the same problem though and found (forgot) that using the #each changes my context.
The solution was to wrap the #each:
{{#with this as context}}
{{#each fruitBins}}
<tr>
<td>{{id}}</td>
<td> {{view Ember.Select
content=context.fruitTypes
optionLabelPath="content.name"
optionValuePath="content.id"
prompt="Select a Fruit Type"
}}
</td>
</tr>
{{/each}}
{{/with}}
Related
I have a toggleProperty in the container to toggle a set of actions on each item. The problem is, when the toggle button on 1 item is clicked, every item is toggled, instead of the one that's clicked.
I would love to know how to toggle only the clicked item, not everything from the list.
I am using the ember-cli to build my application.
My category model:
import DS from 'ember-data';
export default DS.Model.extend({
pk: DS.attr('string'),
category: DS.attr('string'),
products: DS.hasMany('product'),
});
My category route:
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.findAll('category');
},
});
My category controller
expand: function() {
this.toggleProperty('isExpanded', true);
}
My template:
{{#each model as |i|}}
<tr>
<td>
<a {{action 'expand'}}>{{i.category}}</a>
</td>
<td>
{{i.pk}}
</td>
<td>
{{#if isExpanded}}
<button {{action "deleteCategory"}}>Edit</button>
<button {{action "deleteCategory"}}>Delete</button>
{{else}}
<button {{action 'expand'}}>Actions</button>
{{/if}}
</td>
</tr>
{{/each}}
Since stackoverflow, is not letting me post without adding more text, I would also like to know how to show all the products associated with the category, on the same route (same page), by clicking on each category?
Cheers and thank you.
In controller:
expand(item) {
if (!item) {
return;
}
item.toggleProperty('isExpanded', true);
}
Template:
{{#each model as |i|}}
<tr>
<td>
<a {{action 'expand' i}}>{{i.category}}</a>
</td>
<td>
{{i.pk}}
</td>
<td>
{{#if i.isExpanded}}
<button {{action "deleteCategory"}}>Edit</button>
<button {{action "deleteCategory"}}>Delete</button>
Products:
{{#each i.products as |product|}}
{{product}}
{{/each}}
{{else}}
<button {{action 'expand' i}}>Actions</button>
{{/if}}
</td>
</tr>
{{/each}}
I have a handlebars template where i have a table.
<script type="text/x-handlebars" data-template-name="customers">
<table>
<tbody>
{{#each nomday in allnominationdays}}
<tr class="nomdays" {{action "saveNomDay" nomday on="focusOut"}}>
<td>{{nomday.confirmedVolume}}</td>
<td>{{nomday.variance}}</td>
</tr>
{{/each}}
</tbody>
</table>
</script>
In my controller i have a function which i call from the action saveNomDay defined on the tr.
update: function()
{
console.log('Not Working');
allnominationdays = this.get('allnominationdays');
//this.set('allnominationdays',null);
allnominationdays.objectAt(0).variance = 75;
this.set('allnominationdays',allnominationdays);
},
But my view is not changing when i change the value of the object array. If i set the object array to null the template updates and shows no table. I am not sure what is breaking the binding for the view to update?
the code block updates the view when in a controller function but not when called on a action. But inside the action setting the array of object to null update the view and removes the entire table. Don't know what is going on. New in EmberJS
THanks,
I am too late but better late than never. This is happening because the view is getting rendered before the update in the value can propogate to the screen. Do something like the following code :
--template
{{#if isVisible}}
<table>
<tbody>
{{#each nomday in allnominationdays}}
<tr class="nomdays" {{action "saveNomDay" nomday on="focusOut"}}>
<td>{{nomday.confirmedVolume}}</td>
<td>{{nomday.variance}}</td>
</tr>
{{/each}}
</tbody>
</table>
{{/if}}
--component / controller
self.set('isVisible',false);
var propgationPromise = new Promise(function(resolve, reject) {
//update Value
console.log("promise started");
resolve();
});
propgationPromise.then(function(){
console.log("promise stopped");
self.set('isVisible', true);
});
The behavior that i want is when changing the select is to save it's model
I though about using observable, but i have another problem
my view looks something like this
{{#each item in model.Items}}
<div class="select">
{{view Ember.Select
content=typesLookup
selection=type
prompt="Select Type"
}}
</div>
{{/each}}
so if i went with the observables solution, what i want is to also know the specific item that has changed to update it
add the observer and selection on an itemController.
App.FooController = Em.ObjectController.extend({
type:undefined,
watchType: function(){
console.log('this model changed', this.get('model'));
}.observes('type')
});
{{#each item in model.Items itemController='foo'}}
<div class="select">
{{view Ember.Select
content=typesLookup
selection=item.type
prompt="Select Type"
}}
</div>
{{/each}}
I have the following:
Template
{{#each item in controller.pagedAutomationExceptions}}
{{log item}}
<tr {{bindAttr class="item.rowClass"}}>
<td class="text-center">{{unbound item.BTicket}}</td>
<td>{{unbound item.Reason}}</td>
<td>{{unbound item.TimeReceived}}</td>
<td>
{{#if item.ShowContactVoltageSources}}
{{view Ember.Select
contentBinding="controller.contactVoltageSources"
optionValuePath="content.Name"
optionLabelPath="content.Name"
valueBinding="item.AutomationValue"
prompt="Choose one..."}}
{{/if}}
{{#if item.ShowVoltageField}}
{{view Ember.TextField valueBinding="item.AutomationValue"}}
{{/if}}
{{#if item.ShowEnergizedObjects}}
{{view Ember.Select
contentBinding="controller.energizedObjects"
optionValuePath="content.Name"
optionLabelPath="content.Name"
valueBinding="item.AutomationValue"
prompt="Choose one..."}}
{{/if}}
</td>
<td>
{{#if item.Errored}}
{{/if}}
{{#if item.IsUpdating}}
<btn class="btn btn-primary" disabled="disabled">
Updating..
</btn>
{{else}}
<btn {{action updateAutomationException item target="controller"}}
class="btn btn-primary">
Update
</btn>
{{/if}}
</td>
</tr>
{{/each}}
Controller
(sorry if it's not exact, I'm doing it from memory and I changed it trying to fix the problem)
App.Exception = Ember.Object.extend({
// properties used in template, etc..
});
App.ExceptionsController = Ember.Controller.extend({
init: function () {
this._super();
// ajax request to get exceptions from database
// once inspections are loaded
// set(automationExceptions, response)
// loadMoreExceptions()
},
automationExceptions: [],
pagedAutomationExceptions: Ember.A(),
loadMoreExceptions: function () {
// i have a variable that i store to tell me
// how many exceptions I'm currently showing.
// If there are more, I just add to this variable
// the paging amount, and for those elements
// create a new exception and add it to the
// paged array. This method also seems to work
// because I get more records on the view.
for (; currentTake < newTake; ++currentTake) {
var simple = automationExceptions[currentTake];
this.get('pagedAutomationExceptions').pushObject(
App.Exception.create(simple));
}
},
updateAutomationException: function () {
// ajax post update, this works fine..
}
});
When I try to change the route I get the following error:
Uncaught TypeError: Cannot read property 'IsUpdating' of undefined
If I remove that line then there's some other property it can't read.
I'm not sure what's going on, obviously Ember is somehow getting a hold of an undefined object, but I don't see how. I instantiate all of my objects and push them onto the array.
I had a single view with an each helper similar to this:
<table class="select-sect" cellspacing="0">
{{#each sections}}
<tr {{bindAttr class="highlight:highlight"}} {{action "selectSection" }}>
<td class="key">
{{#each zones}}
<em {{bindAttr style="color"}}> </em>
{{/each}}
</td>
<td class="sect">{{name}}</td>
<td class="price">{{currency lowPrice}} - {{currency highPrice}}</td>
</tr>
{{/each}}
</table>
Binding a dynamic class like this worked very well. If I set section.highlight == true in a controller, the view would update with the appropriate class.
"Calling" code:
zone.section.set('highlight', true);
Because I need to handle some other events on each row, I've migrated the entire table row to a nested view. I'm searching for a way to make the dynamic class work as it used to.
{{#each sections}}
{{#view SYOS.SelectSectionRowView sectionBinding="this" }}
<td class="key">
{{#each section.zones}}
<em {{bindAttr style="color"}}> </em>
{{/each}}
</td>
<td class="sect">{{section.name}}</td>
<td class="price">{{currency section.lowPrice}} - {{currency section.highPrice}}</td>
{{/view}}
{{/each}}
I don't think I can use the same bindAttr solution since it would need to apply to the #view helper. I've also tried classNameBindings & classBinding to no avail. Updating section.highlight no longer triggers this view to apply the dynamic class.
View w/ classNameBindings:
SYOS.SelectSectionRowView = Em.View.extend({
tagName: 'tr',
classNameBindings: ['isHighlighted:highlight'],
isHighlighted: function () {
return this.section.highlight;
} //also tried .property('section')
});
View with classBinding:
{{#view SYOS.SelectSectionRowView sectionBinding="this" classBinding="needsHighlight"}}
in view class:
needsHighlight: function () {
if (this.section.highlight) {
return 'highlight';
}
return '';
} .property('section'),
Neither of these seems to do the trick. Can anyone lend any insight into how to get a scenario like this going?
Thanks much!
try classNameBindings: ['section.highlight:highlight']