I'm trying to set up mass-action checkboxes (for something like Delete Selected Items) in an Ember App. The idea is to make a mass-action dropdown show or hide if any one of the checkboxes are selected. I haven't put in the dropdown yet since I can't figure out how to observe all elements in the array. How can I:
app/templates/clients.hbs
<section id="clients">
<h4>my clients</h4>
<ul>
{{#each itemController="clients/client"}}
<li>
{{input type="checkbox" name="markedForDeletion" checked=markedForDeletion}}
{{#link-to 'clients.show' this}}
{{clientName}}
{{/link-to}}
</li>
{{/each}}
</ul>
</section>
{{#link-to 'clients.new'}}Add client{{/link-to}}
{{outlet}}
router.js
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
export default Router.map(function() {
this.resource('clients', function() {
this.route('show', {path: '/:client_id'});
this.route('new');
});
});
app/routes/clients.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.find('client');
}
});
app/models/client.js
import DS from 'ember-data';
export default DS.Model.extend({
clientName: DS.attr('string'),
clientEmail: DS.attr('string')
});
app/controllers/clients.js
import Ember from 'ember';
export default Ember.ArrayController.extend({
checkBoxesChanged: function() {
// This fires only once, when the /clients/ route is activated
console.log('markedForDeletion in array changed');
}.observes('@each.clients')
});
app/controllers/clients/client.js
import Ember from 'ember';
export default Ember.ObjectController.extend({
markedForDeletion: true,
markedForDeletionChanged: function(){
// This fires correctly
console.log('markedForDeletion object changed');
}.observes('markedForDeletion')
});
Edit: Similar question asked here , but I'm afraid the answers didn't help me all that much.
There are a couple of solutions to this. Since your solution only requires the need for an extra property of being checked, I think that an ObjectProxy will meet your needs. If, however, you needed more functionality, then a component would be a better fit.
Note: Before we dive into the solution, though, it's important to note that ArrayController, ObjectController, and ItemController are all being deprecated.
Since we won't be using itemController, you can remove app/controllers/clients/client.js
app/templates/clients.hbs
<section id="clients">
<h4>my clients</h4>
<ul>
{{#each clientsWithMarker as |client|}}
<li>
{{input type="checkbox" name="markedForDeletion" checked=client.markedForDeletion}}
{{#link-to 'clients.show' client}}
{{client.clientName}}
{{/link-to}}
</li>
{{/each}}
</ul>
</section>
{{#link-to 'clients.new'}}Add client{{/link-to}}
{{outlet}}
app/controllers/clients.js
import Ember from 'ember';
export default Ember.Controller.extend({
clientsWithMarker: Ember.computed.map('model', function(client) {
return Ember.ObjectProxy.create({
content: client,
checked: false
});
}),
// This computed property returns an array of ObjectProxies that
// are checked. It is recalculated automatically
checkedClients: Ember.computed.filterBy('clientsWithMarker', 'checked', true),
checkBoxesChanged: function() {
// This fires only once, when the /clients/ route is activated
console.log('markedForDeletion in array changed');
}.observes('clientsWithMarker.@each.checked')
});
This should work, but I haven't actually tested this specific code.
Here is the working example of Multi-Select Checkbox functionality implementation in ember.
http://alexdiliberto.com/posts/ember-toggle-all-checkbox/
http://emberjs.jsbin.com/coliwiwa/5/edit?html,css,js,output
Basically when looping through each item in array, the itemController sends reference of itself to parentController and parentController maintains these references in an array. Here isChecked
property is defined inside each itemController instead of attaching to array members. We are using this approach in our production code.
Alternative approach could be to use ObjectProxy
and attach isChecked
property on each array item of new array, and observe it.
eg. If colors
is array then
var newColors = colors.map(function(color){
return Ember.ObjectProxy.create({
isChecked: false,
content: color
}
)};
This way we have create newColors array with isChecked
property which we can loop over and we haven't touched the individual items.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.