I have a MVC5 app that is using layout page to control the header and footer ect. The layout page has some sections that are database driven such as the nav bar. I am not sure of the best practice for where to make these calls is. I can think of 2 ways but neither are perfect
Method 1: Pass in data with the pages view model. Don't like this approach has my homepage controller should only be concerned with homepage content, not the layout. This would have to be repeated for each and every view.
Method 2: Ajax to WebAPI controller. Kinda leaning towards this, although I think this means losing stuff like #URL and #HTML which are being used to create links and render custom content.
EDIT: Though of another method
Method 3: Load info into cache on Start. Since this is not info that changes often after initial setup and this code is displayed on every page, caching would be needed anyways.
You should call a controller method from within the view. On your view:
#Html.Action("MyAction", "MyController")
Make sure this action can find everything it needs without having to have values passed in, and you're set. We do this in several projects via service location and/or dependency injection.
Related
I am on a team that is interested in using ui:include to embed external resources in a HTML document. While investigating how to do this, I came across this post: JSF Facelets how to include external html?
BalusC clarifies that is the wrong tool for embedding external resources in a HTML document and suggested using iframes instead. My question is: why is it the wrong tool?
The team I'm on is especially concerned about security. The content is all going to be our own, but there is a concern about cross-site scripting when communicating between iframes. I've read that there are security benefits to using iframes, as well.
Since the answer likely depends on the use case, I will describe mine:
We're using a docking framework called wcdocker (http://docker.webcabin.org/), which allows panels to be added as divs (planning to use ui:include) or via iframes.
From what I've read/experienced so far, my main concern is that you would have to load the entire page for a given panel, even if the user might not actually open it. There will be multiple dockers, and each will have about 50 panels that can be opened. I am concerned that the client will be overwhelmed, compared to a simple link that may/may not be opened in the given docker.
My second concern is with conflicts if the user attempts to open the same panel twice (same ID tags, omnifaces socket conflicts where the backing bean declares a PushContext for a viewscoped recipient, etc.). I have read workarounds for some of this, sounds like a headache...
Their main concern is regarding communication between panels and cross-site scripting attacks. They believe the user's panel communication should be done directly on the client side, so that the server does not have to be hit at all. I believe the user's panel communication should be done on the server side via a custom publish/subscribe approach (not via JMS) where panel A publishes to a custom Java "topic" object and panel B subscribes to that topic.
For context, there will be a maximum of 50 users at a time, and the web application will be fairly complex.
After a lot of research, there is at least one issue with my question: our content will not be "external" at all. It will be content that resides on the same server as the main application.
Anyway, it seems that at least one concern with iframes is having too many view states. This thread is the most relevant to that problem: JSF multiple views limit. There is a limit to the number of views (15): (ViewExpiredException after upgrade to jsf2)
You can increase that limit in the web.xml file, but it may be difficult to identify the right number for the problem described above.
In another thread, BalusC indicates that ui:include is the best way to put an xhtml inside another xhtml (How to include another XHTML in XHTML using JSF 2.0 Facelets?). However, ui:include does not appear to be ideal for dynamic content. With wcdocker, a panel may be added/removed at any time. It may be worth using jquery's load method as an alternative. See this thread for more information, even though it's for PHP's ui:include: Best way of loading/including content? (jQuery's load() vs. PHP's include())
For anyone interested in using wcdocker in a JSF project while avoiding iframes, this code is a good starting point:
myDocker.registerPanelType('My Panel', {
onCreate: function (myPanel) {
var $mydiv = $('<div id="div1"></div>');
myPanel.layout().addItem($mydiv, 0, 1).css('text-align', 'right').stretch('1%', '');
myPanel.on(wcDocker.EVENT.LOADED, function() {
$("#div1").load("thepage.xhtml");
});
}
});
Finally, you may still run into an issue with conflicting id's, particularly if you load the same page twice. This thread may help you to resolve that concern, and it may even be wise to determine ID by a url parameter: Avoiding duplicate ids when reusing facelets compositions in the same naming container
Looking for some thoughts and feedback on making async requests from dust.js template helpers:
Dust.js can make async requests from template helpers, but is it actually a good idea to make use of them? Consider this scenario...
A particular page requires several api requests to be rendered. In the page's route controller, a single async api request gets the bulk of the data for the page and passes the data to the template to be rendered. In the template there are several reusable and standalone dust helpers (can be dropped in on any page) that make their own async requests in order to display their components.
In this situation, all the dust helpers have to wait until the request made from the controller finishes before their calls can be made (when template rendering begins).
It seems that ideally (excluding having one endpoint for all data on the page) all requests should occur in the route controller in order to avoid synchronous calls, otherwise the request chain would be 1) controller requests 2) dust helper requests 3) nested/dependent dust helper requests.
Cons:
route controller complexity by calling n services to build the view model
adding display components to new pages require changes to controller and template instead of just adding a template helper
Pros:
reduce/eliminate synchronous requests and increase performance
easier to understand the view model
What are your thoughts? Thanks!
If you consider to use your templates only server side I would move everything into the controller. I like to have a controller who "controls" all the data needed for the view layer.
If you think about using dust templates in the browser (so ajax calls from the cleint) both ways in my point of view are reasonable from an architectural view.
But I would ask my self some question about user experience before deciding:
How much time would take to complete all the calls from the
controller? Sometimes is better to send partial data to the user and
give to him something to view and load other components later for a
better user experience. But if the overhead is not over some ms, I
would decide to build my page context all in the controller.
Where is the data displayed in the page? Do you need it in the first
part of the page? Or user should scroll to view other sets of data?
If the data is not consumed immediately I would decide to leave it
to the client.
How would I go about denying access to a partial views with node.js/express? I have various different views in my single page web app and would like some pages to not be shown unless a user is logged in. How would I go about doing so? I know this might be vague, but I would like to have a general idea before actually coding in anything.
EDIT:
for example,
since my page is a single page app everything should be pulled up on the main page when any certain button is clicked, and the URL be handled from my side. But, I have the issue that if I type in something like:
http://www.mypage.com/login
the elements load, but they come out wrong. I would like to block the views from showing up unless they are clicked from a button on the main page. How would I do so?
Your help is appreciated.
You can do the basic routing logic and call a method for routes which you want to restrict.
app.get('/partials/view1, routes.partials);
app.get('/partials/voew1', restrict, routes.partials);
In the restrict method redirect the flow to a generic 'restricted' view.
Check this : https://github.com/visionmedia/express/tree/master/examples/route-separation
Partials were obsoleted in Express 3. It's usually better to use the latest version of software.
I am learning nodejs with express and i am creating my first single page application with the help of knockoutjs, i have a lot of routes and i am looking for a way to hide the parameters in the Url other than encoding them, if i have header links like :
http://www.mywebapp.com/login
http://www.mywebapp.com/logout
http://www.mywebapp.com/signup
http://www.mywebapp.com/users/username
http://www.mywebapp.com/users/1-8
can i still make those links appear as
http://www.mywebapp.com
no matter what the route to be called is?
if not possible can someone please explain why?
my application is completely ajax driven.
Well if your app is ajax then the url won't change. You can also wrap the entire thing in an iframe and only navigate inner frame. But keep in mind that this is generally bad practice as history and bookmarks don't work.
I am learning about backbone, and from the examples and tutorials I have gotten this impression:
The initial GET / returns the skeleton page with backbone and the view templates.
Backbone uses the REST API to flesh out the page by GETting the data it needs and adding it into the DOM.
This works, but it seems wasteful in terms of additional HTTP requests, and latency from the perspective of the end user (minimum two round-trips before the page is visible. Actually three in my case, since the API must first ask which widgets are available, and then fetch the details on any available widgets....).
Is there an established, standard method for getting around this? My current candidates are:
Ignore the problem.
Embed the initialization data directly into the original page via inline javascript.
Render the page as if backbone didn't exist. When backbone finishes initializing, it will (hopefully) be in sync with the page as the user sees it. It can correct anything it needs to if things changed in the intervening couple seconds, but at least the user is not left hanging.
Another solution I haven't thought of?
Is there an established way to do this? Is it situation-specific? I am using Node / JS / Express.
Update: I think I found a solution, possibly the "accepted" solution, in Backbone's documentation:
Here's an example using reset to bootstrap a collection during initial page load, in a Rails application.
<script>
var Accounts = new Backbone.Collection;
Accounts.reset(<%= #accounts.to_json %>);
</script>
Calling collection.reset() without passing any models as arguments will empty the entire collection.