Ember.js - How to implement selected item using Ember.Router? - javascript

I'm wondering what the best way is to handle a list of items and displaying an item detail when a user clicks/selects one of the items. An example of this would be showing a list of email messages in the left sidebar and showing the message details in the main content area when a user clicks on one of the messages.
Using #pangrantz's great answer on how to mark active menu item using router infrastructure I was able to come up with a working example: jsFiddle
But there are a couple things that don't seem quite right:
First, in #connectOutlets in the Router's show state, I'm setting the selected message on the controller as well as connecting the outlet with the same object. I would think I could do one or the other.
connectOutlets: function(router, context) {
router.set('messagesController.selected', context);
router.get('applicationController').connectOutlet('message-details', 'messageDetails', context);
}
Second, I'm transitioning to the same state from both the index and show states. I'm not even sure I want to be transitioning to a new state - I just want to hook up the outlet.
showDetails: Ember.Route.transitionTo('show')
Is there anything I can change to make this code more idiomatic? Thanks!

This code looks pretty idiomatic to my eyes. You are right, you do not need to set the selected message. When you connect the outlet for message details it will set the selected message as content on the message details controller.
You should IMO be transitioning from a index to a show state as this is good RESTful practice and also allows users to bookmark individual messages. I would make the URL to the index state be '/messages' rather than '/'.

Related

How to target a list of DOM elements within React

So I'm currently doing Brad Traversys 50 projects in 50 days, but I wanted to do it built in Next.js with React for practice, as that's what I use at my job.
As you can see from me posting here, it's not going so well! I'm already running into road blocks.
I'm trying to create a set of cards, that when one is clicked, it expands out. Outside this, if there is a card already expanded, and another card is clicked, I need the previously expanded card to collapse, whilst the card currently clicked expands.
I'm currently trying to work off an active state, and passing that down to the Panel props, but obviously that just sets all the flex's to be the same and nothing happens. But when I try to define the active useState inside the Panel component, it works, but I can't then target the other active states in the other Panels, to set them to false.
You can see my code on this CodeSandbox https://codesandbox.io/s/nifty-goldberg-5noi4?file=/pages/expanding-cards.jsx
You can see the correct functionality here https://50projects50days.com/projects/expanding-cards/
What's the best way to go about this?
You need a logic like Accordion control in Material UI. As in my comment, here is the example.
https://material-ui.com/components/accordion/#controlled-accordion

Progressive fetch or all at once Master Detail

I am making a master-detail-detail application in React and GraphQL. Let me explain, there is a sidebar which shows products, and then when you click one of the list of products, ANOTHER list is shown in the main window (Master Detail). Here is the kicker, if you click one of the products in the Main window ANOTHER section on the right sidebar is populated with details. So like this:
Master List --> Details List --> Properties of Detail
I have React Router set up nicely and wondering what is the proper way to fetch? There are many ideas about this. For instance, should I structure the call and data for GraphQL to just fetch EVERYTHING onLoad? i.e. Parents (products), Children (product list), and details (details of children. Just fetch everything and setState?
OR, is the proper way to do things using GraphQL, to load ONLY the product list when the application loads, and when a user clicks on a product THEN FETCH the list of children, and when they click a child product, THEN fetch the details.
Just wondering about methodology.... of course when the lists get big, you would have a spinner show in the main pane, and then a spinner show in the details pane I suppose.
GraphQL solves the overFetching situation.... but, should I divide the fetch up when a user clicks and progressively fetch...or fetch everything at once and just click -> map() over the results.
I am curious to hear everyone's take on this.
The answer here is to not fetch the entire JSON tree at once. That would be a huge overfetch. We can create separate collections in MongoDB for the parent items and the child items in a one-to-many relationship, then use GraphQL to fetch exactly what we need in each window onClick/onChange. This seems the most efficient and expedient way since I am dealing with upwards of 10 panes of data and around 50 components. This is a very complex application I am working on.

The correct and clean way to not render a child template in a parent template in Ember

I am overhauling an old project to use ember with firebase for persisting data. It is a restaurant site, I added authentication and I am allowing admin users to add and delete menu items from the restaurant's menu.
My route is set up as follows
Router.map(function() {
this.route('menu', function() {
this.route('add');
});
});
the model functions are working properly but due to the nested route as you add menu items, the menu template grows and grows and pushes the add form way beneath the fold. My question is what is the correct way to get it so that localhost/menu doesn't render when you are on localhost/menu/add?
First option
So it seems that menu and menu.add routes are not related much.
First suggestion is separating them as they are unrelated routes:
this.route('add-menu');
this.route('show-menu');
Second option
But if they are related a bit, one better suggestion is to create a new route to list the menu items. Such as:
this.route('menu', function() {
this.route('add');
this.route('list');
});
By this way, the menu route's template will be empty. (In the menu route, you may want to add a redirect hook to redirect menu routes to menu.list.)
Third option
But I think a far better suggestion is using index routes. Instead of defining the list route above, use index route. The index route will list the menu items.
Have a look at this twiddle.
Index Routes from the Ember Guides.

React Rendering different Children Components on button click

chatbox
profile view
So these are mockups for my social network project.
My question is that when a user logs in he is presented with this view.
There are two parent components THE LEFT PANE and RIGHT PANE.
THE LEFT PANE remains there for the whole session. BUT inside right pane I have to render
Chat box(when someone clicks on a friend from the list).
Pending request Component(When the see pending request button is
clicked)
Search Friends(When make friends button is clicked)
Profile View (When someone clicks on the interactive I button
Priorities:
I do not want to show the change in the address bar when any
component changes. So cannot use Browser Router.
Possible Solution but in doubt
I could use Conditional rendering by attaching some state variable
with each button click and when that button is clicked determining
the state i should render that specific component.
I could use Memory Router in react router in order to keep the code
clean and do not show the change in the address bar.
Help
CAN ANYONE WITH A GOOD EXPERIENCE IN REACT TELL ME IS THERE ANY OTHER WAY OF DOING THIS? AND IF NOT THEN WHICH IS A BETTER OPTION BETWEEN THESE TWO?
Pls refer to the images to get full idea about the situation.
thanks.
P.S. I can only post two links the other two components of pending request and make friends would be loaded the same way inside the right pane.
I think the best way would be to use the memory router Coz it would help to keep your code neat and understandable for reusability

Ember.JS Best Practice: Model vs Controller field binding

I am looking best practices in Ember.JS to fix the following scenario:
The user clicks on the challenges link.
The system displays the list of challenges.
The user clicks on edit challenge button.
The system displays the edit challenge form.
The user updates the challenge name.
The user clicks on the leagues link without saving the challenge.
The system displays the list of leagues.
The user clicks on the challenges link.
The system displays the list of challenges with the updated challenge name.
This issue is occurring because all my text field are binded directly to the challenge model and since the model is updated as soon as you type it updates the text on all the routes. I have a cancel button on the edit form where I do this.get('model').rollback() on the model to cancel out the edits. However this gets messy if you start doing rollback in different place on the page you can click.
The way I was thinking about fixing this issue is to have the form field binded to the controller properties and on each route copy the model properties to the controller properties on the setupController hook. This would prevent edits to impact the other routes.
I am wondering if this best practice in ember or is there a better way to fix this issue?
Thank you
You can use single rollback in deactivate route hook. Then on cancel action you can do transition only.
// edit challenge route
model(params) {
...
},
deactivate() {
this.modelFor( this.get('routeName')).rollback();
}
PS Are you aware that rollback() still doesn't work properly with relations and reduced to rollbackAttributes() in ED 2.0?
Related links:
https://github.com/emberjs/data/issues/2122
https://github.com/emberjs/data/issues/3273#issuecomment-110965145

Categories