easy durandal please wait while loading spinner - durandal

Is there an easy durandal way to clear the view and put a loading or please wait... on the screen so the user gets some feedback to know that it is working until the ajax content loads?
Right now when I click on a something that navigates to a child route and that child route loads a module that has to do a lot of stuff in activate(), it does not switch the nav or clear the screen or give any feedback to the user that it is working and I see them clicking many times over and over and getting frustrated, then just about when they want to give up, the page loads in fine.
I would like to make this default functionality for my app and not have to do something special in every module or on every page, is that possible?
Thanks.

Have you tried to use router.isNavigating? Original Durandal template contains a spinner like this:
<div class="loader pull-right" data-bind="css: { active: router.isNavigating }">
<i class="icon-spinner icon-2x icon-spin"></i>
</div>

A large percentage of the time, what you're looking for can be obtained very simply via:
<div data-bind="compose:ActiveVm">
<div class="text-center" style="margin : 75px">
<i class="fa fa-spinner fa-spin"></i>
</div>
</div>
The inner div can be any arbitrary markup which will display while the viewmodel is going through activation.
Note that this currently only displays the placeholder content the first time this dom section is composed. If you have a section of your application which is being updated via an observable viewmodel + compose approach, you could use the approach here:
Durandal: Showing a 'LOADING...' during composition
For anyone visiting from the future, this issue might be worth checking out in case native support for this is desired:
https://github.com/BlueSpire/Durandal/issues/414

Related

Why are Vue dynamic components destroyed inside loop every re-render?

I run into an issue with Vuejs 2.x version (latest). While rendering a list of item inside a loop, if I make changes to the items then the normal components are not destroyed but the dynamic components will always be destroyed:
I have put a short sample code here:
https://gist.github.com/yellow1912/fc1c053e07c1ca136148484cf7f79d1a
I have also put a codepen here:
https://codepen.io/raineng/pen/zYGOXYY?editors=1111
<nl-test inline-template>
<div>
<div v-on:click="increase"> increase here please </div><br><br>
<div v-on:click="decrease"> decrease here please </div>
<ul>
<li v-for="(value, key) in getItems()" :key="key">
printing
<component :is="getItem()" :key="key"></component>
<nl-test inline-template>
<div>
this is a test here
</div>
</nl-test>
</li>
</ul>
</div>
</nl-test>
To see what I mean, open the console tab on codepen, click the add item and you will see that the dynamic component items are destroyed and re-created everytime.
I found out why, I need to use keep-alive:
https://v2.vuejs.org/v2/guide/components-dynamic-async.html
To quote:
When switching between these components though, you’ll sometimes want
to maintain their state or avoid re-rendering for performance reasons
Recreating dynamic components is normally useful behavior, but in this
case, we’d really like those tab component instances to be cached once
they’re created for the first time. To solve this problem, we can wrap
our dynamic component with a element
Wasted 2 days on this issue and then I found the answer just a moment after posting this on StackOverflow. Hope it helps someone.

vue-router's router-link with actual refresh?

I'd like to my "SPA" refresh when I click a link, instead of its default behavior where you see the minimal component replacement.
It sounds like I'm killing the best part of SPA, but I feel that the links without refresh cause more troubles than benefits - the worst one I suppose is that the page doesn't apparently respond if you click a link to the current page, which is rather confusing in my opinion:
<!-- You click, then of course nothing happens when you're at HelloWorld -->
<router-link :to="{name: 'HelloWorld'}">link</router-link>
Okay, I didn't know that a normal <a> tag works as my expectation if history mode is used, so I ended up doing this:
<a :href="$router.resolve({name: 'HelloWorld'}).href">link</a>
or maybe just:
link
Thanks akai, I use your help in the case when I want to use the same component. I have a list of categories and when I click on a certain category page needs to be reloaded.
<a :href="$router.resolve({name:'category', params: {id: category.id}}).href">
{{category.name}}
<span>({{category.posts.length}})</span>
</a>

Aurelia eating my Bookmarks

I am working on a legacy application that is being rewritten using Aurelia, the application has a bunch of static html in a tblHelp that needs to be displayed. I am using innerhtml.bind on a div in my view to databind the stored static HTML into the view. Each record is essentially a document complete with a full table of contents that links to other divs within the document (Bookmarks).
Something like:
<div id="toc">
<h1>Table of Contents</h1>
<ul>
<li>Section 1<li>
<li>Section 2<li>
</ul>
</div>
<div id="section1">
<h2>Section 1</h2>
<p>Paragraph Text...</p>
<p>Back to Table of Contents</p>
</div>
<div id="section2">
<h2>Section 2</h2>
<p>Paragraph Text...</p>
<p>Back to Table of Contents</p>
</div>
When I display the resulting page in my Aurelia view and click on the links, rather than moving to the proper Div on the current page, it seems to be attempting to route to an unknown route and ends up returning to the home page (that is my unknown route behavior). How do I make the Aurelia Router know that I am just moving around the same page and do not require it to route to another page?
I think you need to change your <div id= to <a id= which is the correct syntax for anchors. Hopefully Aurelia will recognize them as legitimate anchors when formatted correctly.
Also, since an anchor tag shouldn't wrap the whole content, you'll just open and close it at the top of the div. You can even leave the divs there but should not duplicate the id.
Update:
That being said, I created a GistRun that actually demonstrates that Aurelia should be able to handle the <div id= anchor targets. So, I'm not exactly sure why you're having problems.
Maybe this GistRun or the more standard <a id= approach will help you.

Closing Modal as cshtml page properly

I'm trying to properly close a modal when if I press the x button.
At first i tried doing this in the main index.cshtml page
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
#Html.Partial("Create")
</div>
</div>
and when closing the modal in my create page i had this
<button type="button" class="close" data-dismiss="modal">×</button>
And the modal closed properly but this was a popup from the main screen.
Although it technically worked I wanted the screen to be a bit bigger. So I tried doing this in the index.cshtml page.
#Html.ActionLink("Create new link", "Create")
The create screen still has the same design with the inline class of "modal-content" but the close button doesn't seem to work. I wasn't sure if it was because the ActionLink part is treating it as a brand new page since most links i looked online seem to say include the "data-dismiss="modal"" part and everything is fine.
If I do another actionlink back to the main page that completely refreshes the page and that isn't what I want because it refreshes the data that the user currently has. There's dropdown lists, query results and filtering done.
Is there a way to treat a modal page like a cshtml page properly so that I can close it without completely refreshing the entire page? Or am I going about this problem the wrong way.
Using Html.ActionLink, literally just drops a static a tag to the page. When you click on that, the entire browser view is changed to the new URL. In this context, "closing the modal" doesn't make sense, because there's no modal. You're just display the response from an action that just happens to be the content from a partial view.

Good way to integrate query-layout with reactive templates + async data sources?

I'm working on a Meteor app that gets data from Facebook & I would like to use jquery-layout for presentation. I suspected that there might be some "subtleties" when trying to use jquery to modify HTML in reactive templates, so I set up a relatively simple test case that goes something like this (paraphrased for brevity)...
<body>
{{> mainTemplate}}
</body>
<template name="mainTemplate">
{{#with userInfo}}
{{> partialNorth}}
{{> partialWest}}
{{> partialCenter}}
{{> partialEast}}
{{/with}}
{{layItOut}}
</template>
Template.mainTemplate.userInfo returns contents of a Session variable that starts with a default value and asynchronously get updated with info from Facebook.
Template.mainTemplate.layItOut sets up a call to Meteor.defer with a callback fcn that actually executes the 5 lines of jquery-layout code.
And that seems to work pretty well...
the initial display is as expected/intended (although there's a brief period where the page is not laid out)
any updates to the reactive context cause re-execution of the layout (again, w/brief-but-visible re-layout)
So, why am I whining? Mostly I would like to find a cleaner approach that does away with the noticeable re-layout activity.
I could make the reactive contexts more granular, but I'm not sure that this would really help.
Alternatively, I suppose I could experiment with directly controlling rendering (e.g., via Meteor.ui.render() , but that sounds like a lot of work ;-)
I think what I'd really like is either
a) a way to hook into Meteor render events
or better still
b) a cleaner way to connect query-layout to templates
Thoughts?
So I managed to educate myself enough to answer my own question in case anyone else finds it useful. Bottom line is that I was wrong on several levels; making the reactive contexts more granular is the answer (or at least an answer).
In the example I gave, I made the whole page reactive by placing all of the rendering within the #each construct. What I now do is try to make the reactive contexts as small as possible so that only a (relatively) small part of the page is re-rendered on any reactive change and all of the reactive elements are contained below (or way below) the level of the jquery ui elements.
I.e., something like this:
<body>
{{> mainTemplate}}
</body>
<template name="mainTemplate">
{{#with userInfo}}
{{> partialNorth}}
{{> partialWest}}
...
{{/with}}
{{layItOut}}
</template>
<template name="partialNorth">
<div class="ui-layout-north"> <-- definition for jquery-layout north panel
<h1>This is the north pane</h1>
<p>The user data go next:</p><br />
{{> templateUserData}}
</div>
</template>
<template name="templateUserData">
<div>
{{#with theUserData}} <-- Assumes a helper function 'theUserData' for this template
<p>First name: {{first_name}}</p>
<p>Last name: {{last_name}}</p>
...
{{/with}}
</div>
</template>
Once you have the reactive elements below the jquery ui elements (I have tried it with panels, tabs, accordions, buttons and pop-ups so far) the whole thing works just like it said it would in the shiny brochure! ;-)