Question

I’m currently building a photo approval app on Ember.js. Photos in the model have a default of approved = true. Within the app, clicking a photo toggles this state, so they can be blacklisted quickly.

I want to set up some routes that filter and show approved = true, approved = false and all photos.

My router.js:

App.Router.map ->
  @resource "photos", ->
    @resource "photo",
      path: ":photo_id"
    # additional child routes
    @route "approved"
    @route "disapproved"\

My photo.js model:

App.Photo = DS.Model.extend(
  name: DS.attr("string")
  description: DS.attr("string")
  image_url: DS.attr("string")
  approved: DS.attr("boolean")
)

Here is where the problem code lies, in my photos_route.js:

App.PhotosRoute = Ember.Route.extend(
  model: ->
    App.Photo.find()
)

App.PhotosApprovedRoute = Ember.Route.extend(
  model: ->
    @store.filter "photo", (photo) ->
      photo.get("approved")

  renderTemplate: (controller) ->
    @render "photos",
      controller: controller
)

App.PhotosDisapprovedRoute = Ember.Route.extend(
  model: ->
    @store.filter "photo", (photo) ->
      not photo.get("approved")
  renderTemplate: (controller) ->
    @render "photos",
      controller: controller
)

And finally, here is how I’m displaying things in the templates:

{{!-- application.hbs --}}
<header id="header">
  <h2>{{#link-to "index"}}Home{{/link-to}}</h2>

  <nav>
    <ul>
      <li>{{#link-to "photos"}}All photos{{/link-to}}</li>
      <li>{{#link-to "photos.approved"}}Approved{{/link-to}}</li>
      <li>{{#link-to "photos.disapproved"}}Disapproved{{/link-to}}</li>
    </ul>
  </nav>
</header>

<div id="content">
  {{outlet}}
</div>

{{!-- photos.hbs --}}
<h1>Photos</h1>
<ul>
  {{#each controller}}
    <li class="masonry-brick">
      <h3>Approved: {{approved}}</h3>
      {{input type="checkbox" checked=photoApproved class="toggle"}}
      {{#link-to "photo" this}}{{name}}{{/link-to}}
      <img {{bind-attr src=image_url}} alt="Logo">
    </li>
  {{else}}
    <li>There are no photos.</li>
  {{/each}}
</ul>

{{outlet}}

How would I re-adjust my photos_routes.js to get the desired behaviour?

Was it helpful?

Solution

The filter function on Store takes two arguments, a query, that is used by the adapter to filter server side and a function to keep the filter live for new or modified object (update stuff in memory). The function signature you're using looks more like the one you use for an Array.

Have a look at the documentation: http://emberjs.com/api/data/classes/DS.Store.html#method_filter

An untested version of the routes:

App.PhotosApprovedRoute = Ember.Route.extend(
  model: ->
    @store.filter "photo", {approved: true}, (photo) ->
      photo.get("approved")
)

App.PhotosDisapprovedRoute = Ember.Route.extend(
  model: ->
    @store.filter "photo", {approved: false}, (photo) ->
      not photo.get("approved")
)

PS. It seems a bit redundant to me. I think the third parameter (predicate) could be inferred by the query... but that's how I understand how it's now according to the docs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top