Unsure of the semantics of React - node.js

I'm quite new to react and trying to wrap my head around the semantics.
I am building a map based application and the primary parts of the site are the map, the navbar and a search menu which pops up over the map and allows you to select a search which is populated from an ajax request.
Here are some questions which come to mind:
Where should I complete my ajax requests, should that all be contained in the map component? If so, how do I pass the parameters for the request, if the answer is pass it to a function in map then how do I call the function from inside my search menu component?
My app is currently organised like so:
export default class App extends React.Component {
toggleSearchMenu() {
this.refs.searchMenu.toggleVisible();
}
render() {
return (
<div className="pure-g">
<Nav>
<NavButton onClick={() => this.toggleSearchMenu()}>Searches</NavButton>
</Nav>
<Map lat="53.15" lng="-0.5" zoom="9" />
<SearchMenu ref="searchMenu" />
</div>
);
}
}
As you can see, I have resulted to showing and hiding the menu from a function within my app component which doesn't feel right somehow?

As you know, React is only responsible for rendering the views, but it doesn't define how to structure the actual logic of your app. Facebook suggests to use the Flux architecture for that. This site and video should get you on the right track: https://facebook.github.io/react/blog/2014/05/06/flux.html
Basically, you want all actions to enter the same "pipeline", no matter where they come from. Logic and some state is kept in "stores" (sort of a hybrid between a Model and a Controller) and finally components listen to changes in those stores and then re-render themselves.

Related

How to pass context to a React/jsx view?

I'm new to React, and I'm trying to figure out some basics. In other template engines such as EJS or Jade, you are able to pass in a context variable when you are rendering the view file in your routes/controller file. However, I have not found any way to do this with React/jsx. I should note that I am working with Express.
I am actually uncertain if jsx is a view engine, or if React somehow was one built in. In either case, I do not know how to pass context from the server to the view file.
For example, if I wanted to load profile information (that is stored on the server/backend), how would I pass that to my front end jsx view file in React/jsx?
that's simple. There is a mess in MVC terminology, but I think it would be okay to say that React component is not just the "View", but "View + Controller".
As a direct analogy to the templating engines, component's render() function is your template. And component.state (which is local to the component) and component.props (arguments received from the upper component) both can be used as a "context".
If you want some really close analogy to the React component in the conservative part of the JS world, it's Backbone's View (which is again the view + controller if we use original MVC terminology; as I told - it's a mess). Conceptually, it's the same thing. JSX is used in render() instead of EJS (or whatever), that's it.
Btw, React's context concept is something different. Think of it as
props which are visible to the whole component subtree starting from
the component where the context is exposed.
For example, if I wanted to load profile information (that is stored on the server/backend), how would I pass that to my front end jsx view file in React/jsx?
In the simplest case, you create the top-level React component, which would load the stuff you need on mount (componentWillMount()), put it to its local state when you'll receive the response from server (this.setState(...)), and pass elements of its state (this.state) down to the subcomponents as props (<List items={ this.state.items } />) in its render() function.
Whenever state is modified with this.setState(...), the whole component subtree will render again. That's how it works. In the simplest case.

Sub windows that stay with all view in MVC

I have an existing MVC application with three main views.
My new task is i need a popup or a window or something that shows some statistic data and that windows always visible on top end of all view and user can still continue there work on the different views.
Kind of lIke a widget that always visible on ur screen no matter what you are doing on ur computer.
I need ideas/suggestion to implement this on my MVC application.
You can implement this as a partial view.
In your Html code you can write something like this:
<html>
<head><title></title></head>
<body>
#Html.Action("Menu", "ControllerName", new { myParam="00" }); //last value can be null if you do not have any parameters.
<h1>Welcome to the Index View</h1>
</body>
</html>
You should also make a controller for this menu, which returns a partial view.
This is aslo a cshtml page, which will be injected at the place where you call the #html.Action()
public class MyController {
public ActionResult Menu() {
var menu = GetMenuFromSomewhere();
return PartialView(menu);
}
}
I hope this helps. this article explains this more in depth.

Automatically provide data to Express partial views

I'm writing an Express 4 app, and am currently using twig.js as the view engine since I find it comfortable, though I could be persuaded to change this engine.
I've done a lot of development with PHP/Laravel and have gotten used to what in that camp they call view composers. Using these I can write a composer for a particular view, whether it's a main page view, a layout which other views extend, or a partial other views include. The composer does any necessary logic to prepare whatever data the view needs, and then attaches it to the view's context so it's available during rendering.
For example, I might have a partial which shows the current user status, so if they're logged out it'll maybe have just a log in button, and if they're logged in it'll have their icon, username, and a menu to let them log out etc. The corresponding composer would check to see if a user is logged in, and if so attach the relevant data about the user to the view's context. It then doesn't matter which page includes this partial; the data will always be available without me having to remember to add that specific data to the context passed to the page's main view.
Is there some equivalent in Express? Or does it depend on the template engine I'm using?
Currently, views that are rendered using res.render() need to have their data passed in on every res.render(). If the view uses a partial template that requires certain data points, the view that uses that template will need to have that value passed in through res.render(). So in short, you always need to pass the data in regardless if the data point is required by a partial template that might be shared. When using view engines, nothing is automatically provided to the view.
Are you asking if it's possible to have some view A, that includes partial P_A and be able to pass some data to the partial that's not dependent on routing, i.e wherever you are on the site / app your partial has data bound to it (totally independent of both the route / url and view ) which you could use for your logged in status ?
if so then create your partial, let's use a navigation / menu partial:
please note that this example uses ejs for templating
<nav>
<ul>
<!-- pass the data upon call / include-->
<% for(var i = 0, len=navigation.length;i < len;i++) {%>
<li><%=navigation[i].Text%></li>
<%}%>
</ul>
</nav>
Call / Include your patial on a view
view.ejs
<%- include('nav', { navigation : [{Text : 'Items' ,href : '/' },{Text : 'People' ,href : '/names' }] } )%>
To my knowledge there is nothing like that in expressjs.

ServiceStack.Razor PartialViewResult equivalent?

Is there a way to return the ASP.NET MVC equivalent of a PartialViewResult (stand-alone partial) in ServiceStack.Razor?
In my service, I would like to return the response DTO as a rendered Partial as opposed to a complete View; again, I just need some rendered HTML snippets for this service.
The use case is to make an AJAX call to a service and then have the service returned the rendered partial.
In one of my views, I just tried the following, but it is still returning the full HTML markup and not just the small snippet.
inside travel.cshtml...
#model TravelScenarioResponse
#Model.Name
You can specify to not use any Layout with #layout "", e.g:
#layout ""
#model TravelScenarioResponse
#Model.Name
Otherwise if you want the same view to be used with multiple layouts and as a partial you can add an Views/Empty.cshtml that just contains:
#RenderBody()
And use that layout in any of the View/Template overrides documented in EmailContacts. E.g. you can decorate your Service or action with a [ClientCanSwapTemplates] attribute, e.g:
[ClientCanSwapTemplates]
public class MyService : Service { ... }
And then the client can specify what view they want to render service with, so you can view a partial by specifying ?Template=Empty on the query string, e.g:
http://razor.servicestack.net/rockstars?Template=Empty
http://razor.servicestack.net/rockstars?View=AngularJS&Template=Empty
http://razor.servicestack.net/rockstars?Template=SimpleLayout

multi-stage form strategies

Currently I'm working on building a page for inputting pricing data for different products my company handles. Pricing data is somewhat complicated, and so different forms are needed depending on what item new data is being entered for. Right now my strategy for dealing with this is to split the page into multiple forms, with an AJAX update on the next stage triggered when valid data is entered. Each form contains a ui:include pointed to a method on a controller bean, which returns a string pointing to a xhtml snippet with the appropriate form structure for the previously entered data.
<form id="stageOne"> Some content that triggers an ajax update of stageTwo </form>
<form id="stageTwo"> <ui:include src="#{controller.getStageTwo()"> </form>
And the backing bean method:
public String getStageTwo() {
switch (stageOneContent) {
case 1: return "/context-root/snippetName.xhtml";
case 2: return "/context-root/snippetName2.xhtml";
}
}
This solution feels somehow wrong to me, particularly having the controller method be responsible for knowing the exact location of all the xhtml snippets the calling page might use. I am still relatively new, and feel like I might be missing something. Is there a better way to handle this scenario?
How about just something like this?
<ui:include src="snippetName#{controller.stageOneContent}.xhtml">
You only need to rename snippetName.xhtml to snippetName1.xhtml.

Resources