简体   繁体   中英

Ember Router active item on click or route change

I have a list of posts pulled from the server using Ember Datastore, which I then render in a sidebar list like view, each post generates a href using the {{action}} helper which generates a valid href by looking up the corresponding router state. Clicking on a Post loads it into a content outlet. This all works perfectly.

I want to add a class to an item when it is selected — "is-active" for example — either when clicking on it, or when the router state transitions to the state which matches the href, for example: when the user presses the back button or navigates directly to /posts/24, a Post with ID 24 gets selected.

Ideally I would like the solution to this be separated from the actual Post record as it is purely a presentation thing and I want to also use this approach for highlighting menu items using the same principle.

What is the generally accepted way to do this?

Edit:

App.Router: Ember.Router.extend(
  root: Ember.Route.extend(
    goToPostsIndex: Ember.State.transitionTo('posts.index')
    goToAbout: Ember.State.transitionTo('about')
    goToShowPost: Ember.State.transitionTo('posts.show')

    index: Ember.Route.extend(
      route: '/'
      redirectsTo: "posts.index"
    )

    posts: Ember.Route.extend(
      route: '/posts'

      index: Ember.Route.extend(
        route: '/'
        connectOutlets: ((router) ->
          router.get('applicationController').connectOutlet('posts', App.posts)
        )
      )

      show: Ember.Route.extend(
        route: '/posts/:post_id'

        connectOutlets: (router, post) ->
          router.get('postsController').connectOutlet('post', post)
     )
   )

     about: Ember.Route.extend(
       route: '/about'
       connectOutlets: (router) ->
         router.get('applicationController').connectOutlet('about')
     )

    )
  ) 
)

Here is a fiddle of my current setup: http://jsfiddle.net/Pts7Q/31/

If you provide a jsfiddle with example code you'll probably get a much more precise and complete answer to your question.

With that said, one approach could be to create an "isSelected" Post attribute that is bound to a selectedPostController (or selectedPost computed property). On click or router/state initialization from url, you could set the value of selectedPostController to the selected item, triggering the bindings to update isSelected to true for the current post and false for all others.

Then, following the ember docs at http://emberjs.com/documentation/#toc_binding-class-names-with-bindattr ,

"The class attribute can be bound like any other attribute, but it also has some additional special behavior. The default behavior works like you'd expect.

If the value to which you bind is a Boolean, however, the dasherized version of that property will be applied as a class (if the boolean is true):

 <div {{bindAttr class="isSelected"}}>
   Post title here
 </div>

This emits the following HTML (if true it will be added, if false no class will be added):

 <div class="is-selected">
   Post title here
 </div>

Then style the is-selected CSS class to look however you want.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM