Make DerbyJS only re-render certain DOM nodes - javascript

The way DerbyJS (http://derbyjs.com) seems to work at the moment is that it replaces everything in the body tag of the document whenever you click a link.
Is there anyway to say use the template, but replace the content inside #main-content with that instead of the whole body?
Navigation on the left is fixed and doesn't need the benefits of realtime interaction.
Why this is an issue is needing to run some Javascript on the page load to set the size of some containers based on the size of a users browser window, and once I click a link, this setup gets wiped and recreated, and of course, the Javascript doesn't run again, because the document itself hasn't refreshed, just the body.
This would also allow me to write nicer jQuery bindings for the most part, $('element').click(, rather than $('html').on('click','element', ...
Any thoughts, or is this a step too far for this framework at this point in time?
P.S. As I'm only just getting started with Derby, and realtime frameworks in general, maybe what I'm trying to do isn't best practice anyway? I chose Derby because I like the UX part of initial render on the server, then the rest in the client, but sharing routers, which reduces the duplication of code. Open to any better ways of achieving this.

There is no way to rerender part of body on page reload. Just whole body.
You can use app.enter hook to run js code after every page render.
No need to use jQuery bindings, use Derby bindings

I fully agree with Vladimir's answer, just trying to add something to it.
It should be possible to re-render part of the UI through transitional routes (http://derbyjs.com/#routes). In your case it seems like app.enter is the way to go though.

Related

Language set up with out loading whole page

Are there any alternate way of below code to set app language? Below code refresh the whole page always that gives bad experience to users.
window.location.search = "sap-language=EN";
This is also one way to achieve.
sap.ui.getCore().getConfiguration().setLanguage("EN");
However, some standard controls after rendered don't change the labels. Let me know if there are any other way that help here because loading whole page doesn't make any sense.
You can use Ajax by getting all the new markup and replacing the existing content by the reloaded content.
It might create some issues with other running scripts like loading images and sliders etc that holds a reference to an element so you have to reinitialize every single script that is running on settimeout() on your page.
Moreover you can use jQuery Localisation plugin

Unload reactjs component

I have got a website, that is lazyloading react scripts from different sources. For each script loaded, we provide a div with the name of the script as id. As soon as the script is loaded, it searches for the div with the id and renders the components.
As the site is displayed on a stationary tablet it does not reload very often and the memory footprint gets pretty big. Is there a way to completely unload a react script without reloading the website? Is there even a way to just unload any
kind of script? I guess the garbage collector is responsible for this, but currently its not even removing scripts / components that have unmounted a long time ago.
As I was searching for a solution, I found this thread about angular. I'm basicly looking for a way to do the same with react (Even tho I didn't test the angular solution).
Before removing the script tag and the container DOM node, you can use unmountComponentAtNode to allow React to do its cleanup.
ReactDOM.unmountComponentAtNode(document.getElementById('root'));
Use a design pattern that uses conditional rendering and check in the componentDidMount if either data is returned or the specific section is to be rendered.

MWC: how to rerender on URL change

Heyo everyone,
story time - skip if you don't care
I'm just starting out with Meteor + Polymer using Synthesis by #aruntk and I'm very happy about the results and greatful for the time he's invested in this project. There's one issue I'm having though.
I've previously only changed a iron-pages object to change the content of my view. Putting that in a FlowRouter like FlowRouter.route("/", action: {ironpages.select("home");}); works just fine. However, my site is getting more complex and I want to rerender a whole section now. I'm being told to do it reactively which is (to my poor understanding) the preferred way of building Apps here.
tl;dr - skip to here if you don't care about stories
So what I did is just putting mwcLayout.render("test-layout",{"main":"yas-manual-page"}); in my Router action. However, I have to reload to make the changes visible which is not what I want.
the router action is being called when changing the URL
the mwcLayout.render() call works if I reload the page once in the initial building of the site
calling mwcLayout.render() again at a later point does not do anything
I've read up on the topic and people say it's a problem with single-page apps and not building it reactively and whatnot, but I have no idea how this is not reactive. It's reacting to the URL change.
Please, if you have a minute, share some insight with me, I'm really stuck. :slight_smile:
Have a wonderful day y'all!
disclaimer: it's a repost form the Meteor forums which suggests coming here instead.
This behavior is added as a feature of mwc layout to prevent multiple re rendering during each route change. Workarounds here are to create another mwc layout or to set third argument forceRender. From the mwc:layout docs
forceRender
In mwc:layout we dont re render the layout unless the new layout is not equal to the current layout or forceRender argument is set. This is to prevent unwanted rerendering while changing routes(even if you change a param/queryparam the route gets rerun so does the render function written inside FlowRouter action). forceRender comes in handy when you have to change the rendering while keeping the current layout.
...
<mwc-layout id="demo-landing">
<div region="header"></div>
<div region="main"></div>
</mwc-layout>
...
imports/startup/client/router.js
...
action:function(params,queryParams){
mwcLayout.render("demo-landing",{"main":"test-layout1","header":"test-header"});
}
...
Now if you try
mwcLayout.render("demo-landing",{"main":"test-layout2","header":"test-header"});
from console it wont work since layout is not changed and forceRender is not set.
This works->
mwcLayout.render("demo-landing",{"main":"test-layout","header":"test-header"},true);

How to perform navigation in Windows Store App using Blank App Template

I'm making a game using JavaScript, currently I'm using window.location = "somepage.html" to perform navigation but I'm not sure if that is the correct way to do it. As I said in the title I've choosed Blank App Template so I do not have any navigator.js or something like.
Can you guys tell me the best way to do it?
Although you can use window.location to perform navigation, I'm sure you've already noticed a few of the downsides:
The transition between pages goes through a black screen, which is an artifact of how the underlying HTML rendering engine works.
You lose your script context between pages, e.g. you don't have any shared variables or namespaces, unless you use HTML5 session storage (or WinRT app data).
It's hard to wire up back buttons, e.g. you have to make sure each destination page knows what page navigated to it, and then maintain a back stack in session storage.
It's for these reasons that WinJS + navigator.js created a way to do "pages" via DOM replacement, which is the same strategy used by "single page web apps." That is, you have a div in default.html within which you load an unload DOM fragments to give the appearance of page navigation, while you don't actually ever leave the original script context of default.html. As a result, all of your in-memory variables persist across all page navigations.
The mechanics work like this: WinJS.Navigation provides an API to manage navigation and a backstack. By itself, however, all it really does is manage a backstack array and fire navigation-related events. To do the DOM replacement, something has to be listening to those events.
Those listeners are what navigator.js implements, so that's a piece of code that you can pull into any project for this purpose. Navigator.js also implements a custom control called the PageControlNavigator (usually Application.PageControlNavigator) is what implements the listeners.
That leave the mechanics of how you define your "pages." This is what the WinJS.UI.Pages API is for, and navigator.js assumes that you've defined your pages in this way. (Technically speaking, you can define your own page mechanisms for this, perhaps using the low-level WinJS.UI.Fragments API or even implementing your own from scratch. But WinJS.UI.Pages came about because everyone who approached this problem basically came up with the same solution, so the WinJS team provided one implementation that everyone can use.)
Put together then:
You define each page as an instance of WinJS.UI.Pages.PageControl, where each page is identified by its HTML file (which can load its own JS and CSS files). The JS file contains implementations of a page's methods like ready, in which you can do initialization work. You can then build out any other object structure you want.
In default.html, define a single div for the "host container" for the page rendering. This is an instance of the PageControlNavigator class that's defined in navigator.js. In its data-win-options you specify "{home: }" for the initial page that's loaded.
Whenever you want to switch to another page, call WinJS.Navigation.navigate with the identifier for the target page (namely the path to its .html file). In response, it will fire some navigating events.
In response, the PageControlNavigator's handlers for those events will load the target page's HTML into the DOM, within its div in default.html. It will then unload the previous page's DOM. When all of this gets rendered, you see a page transition--and a smooth one because we can animate the content in and out rather than go through a black screen.
In this process, the previous page control's unload method is called, and the init/load/processed/ready methods of the new page control are called.
It's not too hard to convert a blank app template into a nav template project--move your default.html/.css/.js content into a page control structure, add navigator.js to default.html (and your project), and put a PageControlNavigator into default.html. I suggest that you create a project from the nav app template for reference. Given the explanation above, you should be able to understand the structure.
For more details, refer to Chapter 3 of my free ebook, Programming Windows Store Apps with HTML, CSS, and JavaScript, Second Edition, where I talk about app anatomy and page navigation with plenty of code examples.

How much content being replaced with an AJAX call is too much?

I run into a common problem when trying to do AJAX development. Where possible, I like to try and just update data in an existing layout, and not the layout itself. For example, take the div below:
<div id="content-5">Here is some content</div>
I would get the updated value for content-5 from the server and just replace the contents of content-5 with the value. This makes a lot of sense for simple data replacements where the value is always going to be displayed in its pure form.
Sometimes the content is more complicated, and I have to actually get more than just raw data... maybe there is some logic to determine how a value is displayed and perhaps the style needs to be different depending on the data inside. In that case, I generally produce the HTML on the server side and inject the HTML into the element instead of just raw data.
Example: A status field from the controller comes back as "complete", but from the design doc, "complete" is supposed to show the user the text "Available" and it needs to be styled in a way different from other statuses.
Doing this in Javascript would require some in-depth view knowledge that the template layer probably already handles. The end result would be the same (code snippet below), but the difference is that there could possibly be some code duplication and a far more complicated Javascript layer.
<div id="content-5"><span class="success">Available</span></div>
Without fail, the requirement comes up that the system will need to handle "new" contents as well. The easiest solution to implement is to just get all of the content's at the same time so that I do not need to handle the extra complexity of injecting a new element instead of just replacing existing content.
So, I create a new template, wrap the contents in another element with an ID, and bulk replace all of the content divs at the same time any time there is a change.
<div id="allContent">
<div id="content-1">Some content A</div>
<div id="content-2">Some content B</div>
<div id="content-3">Some content C</div>
<div id="content-4">Some content D</div>
<div id="content-5">Some content E</div>
</div>
At some point, I have to wonder: Where is the line? At some point it feels like I'll eventually just be replacing the whole page with an AJAX request. Would this really be a problem?
I realize this may be pretty subjective, but what are some good strategies for determining to which level you should be replacing content with AJAX? Replacing just the data seems to be my preferred method when possible as it makes the AJAX controllers very simple. Replacing larger chunks of HTML from a template seems to be the easiest for handling more complicating layout and design issues and also feels like it could be more easily maintained. Are there other options I have not considered?
I expect there will be some discussion about manipulating the DOM programatically, but I personally really dislike this. The code ends up looking pretty horrible and really starts to integrate too much layout and design into the JS layer for my liking. Since I generally work with template libraries of some sort (whether raw PHP, PHP templates like Smarty or JSP in Java) it seems to make more sense to leave as much visual design there as possible.
EDIT
Based on the first few answers, it seems like this is being read as trying to keep the user on the same page but navigating around around the site or otherwise changing the page in a radical way with each update. The question is more about how to determine where the layout work for AJAX calls should happen and whether or not it is an acceptable practice to change large chunks of code with an AJAX request, knowing that replacement code may look nearly identical to what had been there before.
I think the most important requirement is the refresh requirement. If after several AJAX updates I hit refresh, the page I was just looking at should be the page that arrives. If the page reverts to a previous state for any reason then the URL is wrong. If for any reason your AJAX data is going to make the URL in the browser invalid then you should not be using AJAX to fetch that data.
There are exceptions, of course for data the is even newer than the last AJAX request. But that's obviously not what I'm talking about. A live chat screen could receive an update between the last AJAX request and the refresh. No big deal. I'm talking about the logical content and the URL describing it should always be in sync.
Complete personal opinion ex nihil, my rule of thumb is to change no more than 1 "panel" unit or 33% of the page whichever is less.
The basis for this is that the user should be able to clearly recognise the previous page state is related to the new state - how would you feel if you were suddenly teleported into the building to your right? Be gentle with your poor user.
There are also serious technical questions about the benefits of moving and inserting basically a page worth of data, which I think is a bit of an AJAX anti-pattern. What benefit does AJAX provide if you're going to do that?
Your specific question seems dependant on the supposition that the response coming back from your AJAX request isn't "just" data. This feels wrong to me from a separation of concerns point of view: I would expect a page to have all the layout information it requires already, the AJAX response itself to provide nothing more than dumb data/markup, and the JS event handler which created the request to sew the two together, MVC style. In that respect I think, yes, you're doing too much.
(by panel, I mean one logical design element - a menu, a ribbon, an item metadata panel, etc..)
edit: now that I think about it, I think SO's user profile page breaks my rule of thumb with those tab clicks
Depending on whether you want people to be able to to link to / bookmark etc the current page, you might want to navigate the user's browser.
This isn't a concern for some apps like GMail etc, and they won't ever refresh the page.
For myself, I tend to think it's a good practice to navigate the browser when navigating to a logically different place. eg. a person's profile vs. a list of their messages.
Sorry if this is vague, it's rather subjective :-)
A good guideline for something like this is to ask yourself, "Is this dynamic application 'content', or is it content-content?" Your use case sounds like application content that will change with each user. This is probably the best place for Ajax, but with everything, it's always nice not to just have one hammer. You don't want to do too much on one page. For instance, if one part breaks, the entire thing might, thereby frustrating the user.
Anywhere you're looking at actual page content or anything where the information is static, I strongly suggest avoiding the use of JavaScript, as it runs the risk of being invisible to search engines. Make sure anything linking to information like this is crawlable. The first step towards this is dynamic generation on the server side rather than browser side.
If you're using Smarty templates to produce a page, just fragment a template into various meaningful sections - news.tpl, email.tpl, weather.tpl - and have a master.tpl producing the structure of the page and calling child templates.
Then, if you're for example using an AJAX call triggered by a timeout to refresh the news, you can just call the server, cram the necessary data into news.tpl, and return the results into the news div you set up with master.tpl. This way your news layout is always following the pattern of news.tpl. (If you used JavaScript to manipulate formatting bits or set up event handling on document load, you'll need to attach that post-processing to fire after the AJAX call.)
You haven't really gotten specific about the types of things you're trying to replace here, and my initial reaction is that, if a single event is triggering multiple sections of the page to update at once, that's a sign that maybe you should be coallating those sections into a single display.
How much formatting gets done on the server end versus how much gets done on the client end with JavaScript? I'd say server-side formatting if possible, that way you have code that reflects discussions you've made about display layout and logic. Client-side formatting can be used for more interface-based issues - sorting rows in a table and alternating row colors with :odd and :even selectors, showing and hiding divs to create a "tabbed display" without hitting the server since the data won't change just from selecting a new tab, that sort of thing.
Finally, AJAX is one-way. If your web page is a view on a database, this isn't as much of a problem, but using AJAX manipulation to take the place of normal navigation is a terrible idea.
If you were habitually replacing the entire contents of a page using AJAX calls, I would agree that you have a problem. However, it appears to me that you are attempting to carefully think through the implications of your design and attempting, where possible, to avoid what annakata has called this "AJAX anti-pattern."
My rule is a bit simpler: as long as a substantial amount of context (e.g. menu on the left, header, various controls, page title, etc.) remains on a page, I am Ok with replacing almost anything with an AJAX call. That being said, I've never struggled with a page that has as much AJAX-generated code as you are.
I do have one question though: isn't it possible to encode state so that you can just replace some of the Divs in your example rather than all of them? If not, have you thought about doing so?

Categories

Resources