I am building an application using React-Redux + React Router.
So, if user enters https://my-website.com/teams, I want to present him Teams page.
Lets suppose that my app consists of 2 components: Header and TeamsScreen.
I need to load user data to display Header.
I need to load user data & teams data to display TeamsScreen.
What is the right way to achieve it according to Best Practices?
What I have done so far:
1) Introduced a new component, lets name it AuthenticatedUser
render() {
if(!this.props.userData)
return (
<Loader/>
);
return (
<div>
<Header userData={this.props.userData}/>
<TeamsScreen userData={this.props.userData}/>
</div>
);
}
Which loads user data on componentDidMount.
If user data is null, it displays loader. If it's not null, it renders Header and TeamsScreen.
2) I give user data as property to Header. I give user data as property to TeamsScreen.
3) On componentDidMount in TeamsScreen I load teams data.
If teams data is null, I display loader for TeamsScreen. Otherwise I display TeamsScreen.
It seems working, but...In case of slow internet and/or slow database here is how it looks like:
1) There is a big loader for whole page while user data gets loaded.
2) As soon as it gets loaded, I display a header and loader gets moved a bit down till teams data is loaded and I can display TeamsScreen.
I have an uncomfortable feeling that I am doing something wrong.
Please correct me.
Thank you in advance!
Any hints / links to articles will be appreciated.
In this case you should use redux. All code related to fetch data from server will be in actions which which can first start spinner and in turn dispatch another action which will hide spinner and set your data once data returned from server.
Related
Let's imagine I have a Django app which can create and display some kind of articles which are stored in DB. Every article has a status value which means if status=1, it should be displayed, if status=0, it shouldn't.
I create articles on some page of my app, and by default it's status is 1. In the other tab the other page is opened. Every N seconds it sends AJAX requests with the ids of currently displayed articles and gets response with the id and content of new articles which are not displayed yet.
The question is - how can I dynamically render divs for new articles and fill them with data from response, if I don't want to create HTML-markup in success function of AJAX request with append() function or some kind of that stuff? I.e. I create article in one tab and it instantly displays in the other tab.
You can render a template with all new articles:
def new_article_view(request):
old_ids = request.query_params.get('ids')
new_articles = Articles.objects.exclude(id__in=old_ids.split(','))
# this render your template for Articles list.
return render(request, {'new_articles':new_articles}
then in your javascript code you most push the html returned by the django view in the end of the div or something like that.
I am working on xamarin.forms. I have a content page which contains one webview which load 3rd party url(www.xyz.com) site and one button in shell.
On button click event I am trying to get user input data using
webview.eval(javascript: var data = document.getElementById('first-name').value;alert(data)).
It works fine but due to void return type I could not store data in local variable and I have a customrender(webviewrender) but don't know on shell button click event how can I get userinput data from webview
Please suggest me how do I achieve this functionality.I do not want XLab-Hybridwebview.
You'll probably need to have the JavaScript code call out to the external code when the result is available. You could then wrap that whole process in a TaskCompletionSource to make everything nice and easy to use.
I think this is slightly different to the usual controller passing data to the view. I have a Project which has one DocumentOne. Within my app, the user creates a Project. This then redirects them to the show page for this project.
So with the project created, and the user on the show page for that project, I display the project ID. I then provide a select menu where the user can select a Document to display. So say I am in Project with the ID of 1, I then decide to show DocumentOne for this project. This displays a form with inputs for DocumentOne.
When the user fills in the form and submits, the data is saved to the database. The Project ID is the foreign key for DocumentOne. The following route is set up for DocumentOne
Route::resource('projects.documentOne', 'DocumentOneController');
Now I have data for DocumentOne which is linked to the Project with an ID of 1. However, if I now go back to the projects show page and then select Document One from the dropdown again, all I see is an empty form. This is obviously because the controller for this is
public function show(Project $project)
{
return view('projects.show', compact('project'));
}
So I am never passing it data for DocumentOne because theoretically it is not created when the Project is first shown. What I want to do is when the Document is selected in the Projects show page, is to have the form populated with whatever is in the database for that Document. If nothing is in the database, then the form will be empty. I have a DocumentOne Controller, but I dont know if I can link this to the Projects show page. I was thinking about doing something like this in the DocumentOne controller
public function show(DocumentOne $documentOne)
{
return view('projects.show', compact('documentOne'));
}
But not sure this will work. Hope I have not been too confusing and you understand what I am attempting, hoping someone can offer advice on how best to handle this situation.
Thanks
In my previous project, I also deal with such requirement, I thought so. Here my solution to solve such requirement.
Actual code calling from ajax.
Routes
get('setFlashData',function(Request $request){
$final_response = array();
$data_information = $request->except('_token');
$request->session()->flash('cmg_quick_create_data', $data_information);
if($request->session()->has('cmg_quick_create_data')){
$final_response['result']['success'] = true;
}
return response()->json($final_response);
});
But according to you requirement:
$data_information = $request->except('_token');
$request->session()->flash('cmg_quick_create_data', $data_information);
My basic functionality was, to share form data from Quick Create Section which is pop-up form to Full create form section, and whenever user click to "Go To Full Form" button from pop up, ajax call mentioned function which will set the flash data and than on destination side I only check weather its contain the flash data or not. and deal according to data.
#if (Session::has('cmg_quick_create_data')) {
{!! Form::model(Session::get('cmg_quick_create_data'),["class"=>"form-horizontal","data-parsley-validate"=>"data-parsley-validate",'role'=>'form','files'=>true]) !!}
#else
{!! Form::open(["class"=>"form-horizontal","data-parsley-validate"=>"data-parsley-validate",'role'=>'form','files'=>true]) !!}
#endif
I can understand this solution might be different from you requirement but hope full to figure out your solution. Look forward to hearing from you if still unclear from my side.
I have a requirement in my application where in I need to show the UI components(like text field, combo box) based on the values i get from the server side. To be precise, I have a combobox on the page, when the user changes the values i need to send the selected value to server to get information on what needs to be displayed. Without using MVC i implemented it as below
When the user changes the value in the combobox, i refresh(using load method) another store
When i get the data back from the server('datachanged' event) i read the data and create the UI components
Now I am trying to use ExtJS MVC, so i have two questions
How do I access a store which is associated to a controller but not necessarily to any UI components from the view
How can I setup the events of a store in the controller(in the control function) just like we setup events from view
Code i want to setup events from Store like 'datachanged' in controller like below -
this.control({
'viewport > #content-panel' : {
render : this.createMainTabs
}
});
In addition to sha's reply I can say that you may setup your store eventhandlers in your controller. For example you have a combobox with a store, so you could write like this:
this.control({
'#myCombo' : {
afterrender : this.setupStoreListeners
}
});
....
setupStoreListeners: function(combo){
var store = combo.store;
store.on('datachanged', //.....);
}
And one more thing, as sha wrote you could always get store by name, but I use this only when I need to share a store instance between multiple controllers. If I need this store only in one controller, I just save it inside this controller:
setupController: function(){
this.myStore = this.getCombo().store; // now you could use this.myStore anywhere you need
}
To get store object in the controller just use this.getStore('StoreName'), each store by default has its own instance and it doesn't really matter whether it's binded to any UI component you have.
After you get store object you can subscribe to any store events using any method you prefer. I usually like
store.on('load', {...})
Also I would not change anything in UI from the view code. I would put all this customization into controller code.
is it possible to delay loading of some controls on an xpage?
This is the problem: let's say you have a control that does a fultextsearch and displays the result in a repeat control. this ft search might take a long time and will hold the webpage loading in a waiting state until the search result is ready.
I want my page to load most of the data initally, and some "time consuming" controls should be loaded in to the page as a sperate request after the inital load.
this way the user will immediatly see the webpage, but some of the data on the page will load a little bit later without holding the webpage in a waiting state from the server.
possible?
The downside to using rendered is that all the value bindings will still evaluate, even if the corresponding markup isn't sent to the page. So the trick here is making sure the components don't even exist until you want them to.
Every component has a getChildren() method. This returns a mutable List of components, which has a add() method. This allows you to add components to the page on the fly, either while the page is loading, or later during an event. For the purposes of what you're trying to do, you would want to defer adding the "expensive" components until a subsequent event.
Create an event handler attached directly to the view root (), give it a unique ID (e.g. "loadExpensiveComponentsEvent", set its refresh mode to partial, set a refresh ID to whatever div or panel will contain the search results, and set its event name to an arbitrary event (e.g. "loadExpensiveComponents"). This prevents your event from being triggered by actual user behavior. Set the event's code to SSJS that will inject your components.
Then add a script block () to trigger the event after the page has loaded:
XSP.addOnLoad(function(){
XSP.firePartial(null, "#{id:loadExpensiveComponentsEvent}");
});
Your page will load without the search result components. Once the page has fully loaded, it will trigger the component injection event automatically.
For guidance on how to code the injection event, open the Java file that has been generated from your existing page to see what components need to be injected and what to set their values to.
You can pack them into a panel and set their rendered status to rendered=#{viewScope.pageFullyLoaded}. Then in the onLoad event have a XSP. partialRefresh request where you set viewScope.pageFullyLoaded=true
A little ugly but doable. Now you can wrap that code into your own custom control, so you could have a "lazyGrid", "lazyPanel" etc.
Not sure why I did not think of this before. the dynamic content control in extlib actually solves this problem. the dcc can be triggered onClientLoad both using javascript and ssjs afer the page has loaded.
one problem I am facing now is that I am already using the dcc on my site so I need to put another dcc within my dcc. and this seem to be a bit buggy. I have reported it to the extlib team on openNTF.