Angular ui-view with header and content - angularjs

One of the main reasons to use ui-view is listed as having multiple views:
main page
- header
- content
- footer
*other page*
- header
- content
- footer
However, views appear to be tied to states. If I have a header state, I cannot include it in a list detail state with <div ui-view='header'> because header is not a view in list detail.
I am not interested in a hacky answer, as this appears to be the major benefit of ui-router (eg http://www.funnyant.com/angularjs-ui-router/). If I can't get this to work in a clean way, I will go back to the default angular router.
What I have tried
I thought that possibly I would need to access a view in another state to make this work, but google is returning nothing for this.
This solution requires a seperate layout state and that every state be prefixed with root, which seems clunky. If this is an advertised selling point is there no better way to do this?
Multiple Named Views docs relies on all the views being defined for that specific state.
This similar question is answered with "use ng-include".
Another question on how to create a layout state is the closest to what I want, but requires a hacky root scope and that each child scope redefine a container# view.

It looks like you want to have a state with multiple views that is a child of an abstract state.
Abstract states are described here (https://github.com/angular-ui/ui-router/wiki/Nested-States-&-Nested-Views#abstract-states). You are interested in the example "To insert a template with its own ui-view(s) that its child states will populate."
Note that an abstract state can't be instantiated by itself. It is only used when one of its child states are used. In this case you may have only one child state with multiple views for the abstract state.

Related

How to handle layout containers which do not match component hierarchy?

As far as I've understood, in React, components should communicate in an hierarchical order through the nested hierarchy. Given this, how should it be handled when an application's layout container structure don't match the natural/expected/logical component hierarchy.
As an example of my question, I've come up with a scenario based on my app, that I'm not sure how to implement properly:
The screen is split vertically in two halves. This is done having two
div containers side by side. To each halve there's a corresponding
component: ItemsList and ItemDetails.
Nested inside ItemsList, there are several Item components we can
click on.
Each time there is click on an Item, the corresponding defined _itemID prop value needs to be sent to ItemDetails so it can load and display Item details in there.
The problem is, given the component structure, how can ItemDetails be a child of Item and still be on the right section of the screen where it's intended to be. (At least without some weird CSS which I want to avoid).
Here's the layout:
<div className="wrapper">
<div className="itemList" style="width:50%; display:inline-block;">
<div className="item">item1</div>
<div className="item">item1</div>
<div className="item">item1</div>
</div>
<div className="itemDetails" style="width:50%; display:inline-block;">
The details of the selected item.
</div>
</div>
I believe I could send information from a child to parent following up the hierarchy, but this don't seem practical. Considering this scenario is just a simplification of my actual problem (I have a lot more nested components), I believe this would make the code messy and confuse.
Is there a clean, simple way to achieve this in React? Am I missing some concept?
If it were me I would have a container component based off your wrapper. It would handle all state changes and be the source of truth for what the currently selected item is. Then you'd just need to pass a callback from the wrapper component through props down to your ItemsList that would handle setting the state of the active item.
Then you can just pass activeItem as a prop to the itemDetails component. It is a fairly common pattern to have a container component that manages state and passes callback functions down to child components that would allow them to create an action that changes the state of the container
The heirarchy would look like:
<Wrapper> // holds the state of active item and provides functions to change the active item
<ItemList /> // provides a list of items that when clicked sets active
<ItemDetail /> // shows the detail of the currently select item
</Wrapper>
Here is a pen of what i'm trying to explain
http://codepen.io/finalfreq/pen/KgEzgE
This always depends on many things. If you intend for a small project you are fine working with setState and refer to finalfreq's great answer. If you intend to scale well (aka grow without pain) then I would opt for a state management library.
I hate to be the guy who answers a simple question with "Use ... library! It's awesome!", and like I said, it really does not get much better than finalFreq's answer if you don't have the need to grow your app. A redux author even mentions that you should learn react without redux first, and you should not reach for it until you have a real need.
If you use redux then you should never have to worry about component structure for the sake of passing scope. Component structure if I am not mistaken(which I often am XD) should be based on what is easiest to understand and maintain, also performance comes to mind.
Your question is in the context of react, but I think this is really a state management and data communication question. I opt for redux.js lately(a pub/sub like library), but there are many alternatives. Redux requires a bit more typing, but offers extreme explicitness that you may appreciate as the project grows.
But the main reason I would reach for this is that it focuses on functional programming principles, and pushes your state mutations to the outer fringes of your app. This simplifies your code. If there is a bug it's easy to find(All mutations should be in the reducer files. You would also move your calculations to a util file which simplifies your code even more)
http://redux.js.org/

Reactjs - How to make components aware of the current view state?

Tools I'm Using: Reactjs 0.14.7, react-router 2.0.0 (Flux Pattern)
Note: I tagged Redux, just cause I got a hunch(I haven't used it) that what I'm experiencing might be one of the reasons people rave about it.
I understand that react-router already manages which parts of the
component tree are currently in view and renders the components based on the state of the current view tree.
Question:
But what if, based on the components in view, one component needs to know what other components are also in view and behave differently depending on what other components are in view(the view state)? What strategy would you suggest to allow components to be aware of the other components in view?
My Current Solution:
I currently am trying to use the URL to infer this global state, and even parsing it and putting it into a store in order for components to be aware of the view state by listening to changes from that store.
My Issue With This Solution:
In a nutshell managing that view state with a store becomes a highly entangled process with extra actions sprinkled all over the code.
1) Actions must be called for any user event that change the route.
2) Action need to be fired when navigating outside of components(I think its much cleaner to keep action firing in components(feel free to debate that one).
3) You must also consider the back button(currently using react-router onEnterHooks to catch when that happens).
Yet I really like the concept of encapsulating the view state because I can imagine that it creates a nice mental model and also smarter components, but just parsing the current URL and using a utility file to determine the current view state when needed, seems like a much easier/cleaner solution to manage then a store that contains the current view state.
Components should never need to know what other components are being rendered, that's one of the fundamental concepts of React. You're trying to extract the "view state" from your component tree, when your component tree should be determined by your state. If you're already using Flux, you need to keep that information in the store, where it will be made accessible to any component that subscribes.
Flux isn't about making development easier or faster for an individual, it's about enabling practices that make it easier to keep a mental model of what an application is doing. This might come at the expense of some simplicity.
Redux is a refinement of Flux that combines the multiple stores that can be subscribed to individually with a single large state tree, with different parts of the tree created by different "reducers" -- functions that take a state and an action and return a new state. It is exactly "a store that contains the current view state." What you describe is also a pretty good description of the type of development common in hacked together jQuery applications, the type of development React seeks to avoid.
I think the core of your misunderstanding falls into how React component's should be layered. It's a tricky topic, and re-aligning your thought process to accurately understand what is a state vs. prop in your model, is a unique challenge.
But the solution to this problem you are facing is simply to order your components more 'correctly'.
At a high level, each component should only care about the props that are passed to it, and not about anything else whatsoever. However, which props are passed are determined by it's parent Component. As a result, that parent can make those decisions, which then have an end result in the child.
As a simple but practical example;
var Parent = React.createClass({
funcA: function(){
this.setState({propB: 'something new!'});
},
render: function(){
return (
<div>
<ChildA propA={this.state.propA} funcA={this.funcA} />
<ChildB propB={this.state.propB} />
</div>
);
}
});
With this layout of concerns, ChildA is capable of handling user input, passing it to funcA which then impacts ChildB. But all of this happens without the Child components knowing anything about one another whatsoever.

Why isn't my nested state path in Angular UI-Router working?

I'm trying to get one thing to show when the user visits
mysite.com/projects
and another thing to show when they visit
mysite.com/projects/project
However, despite following the tutorial in the official documentation, my set up won't work.
Does anyone see where I'm going wrong? I've looked at everything and compared character for character with the official docs.
See my Plunkr
You are mixing concepts in your states. In some places you are referencing /project as it's own state, in others you are trying to reference it as a child state of /projects.
You can only use projects.project when you are embedding the contents of the child within the template of the parent.
I created two forks of your Plunkr, showing both independent routes and parent/child routes.
Note in the parent/child route, there is an additional <div ui-view></div> in the parent template.
Singular routes: http://plnkr.co/edit/jIMcdTuifE8oRpg83vtN?p=preview.
Parent/child: http://plnkr.co/edit/A85svCnngB7x4PJCUUf9?p=preview
You have two problems in your exemple.
First, your link to the projects.project state is incorrect. You need to put the full name of the state in the ui-sref attribute, so projects.project.
Next, your trying to use nested state. When navigating to the projects.project state, the projects.project state will not replace the projects state. In fact, the projects state will host the child state. So you need to add the ui-view directive inside your projects template (the r1.html file).
Here is a functionnal Plunkr: http://plnkr.co/edit/LyBM4QiKiw8sAoI0jiKo

Nested views vs. nested states

I read the ui-router docs but I didn't understand what is the different between nested views and nested states and how its related to scope inheritance.
Thank!
One state may have few views. Your app may be in one one state at the moment. But display many views at the moment.
So to me views is a sort of children of states if to put it into simple words.

How to keep the username - across all views in Backbone.js

In my app, i have no.of pages. each pages have a separate view for them. But in the header part i need to show the user name on all views rendering.. what would be the best practice for that..
i came across with some of options saying..
1. render the header view even before the router starts
2. use the routers '*' - notation to call the header view always.
3. keep the header view as a sub view of all page views - and keep call header view on all page view..
what would be the correct way...please any one suggest me the best way.
Have a layout view that contains the header and gets rendered only once. Then just render the interior portion of the document as you navigate. Changing the URL and triggering a new route does not always imply the entire DOM needs to re-render. Keep your DOM changes as small as possible. Also study the idea of nested views like you get with Backbone.Marionette for another approach.

Resources