Reputation: 18775
This is my shell.html
defining a navbar, pretty much lifted straight from the tute.
<div>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<ul class="nav" data-bind="foreach: router.navigationModel">
<li data-bind="css: { active: isActive }">
<a data-bind="attr: { href: hash }"><span><i data-bind="attr: { class: glyph }"></i> <span data-bind="text: title"></span></span></a>
</li>
</ul>
<span class="nav">
Welcome <span data-bind="text: app.user.name()"></span>
</span>
<div class="loader pull-right" data-bind="css: { active: router.isNavigating }">
<i class="icon-spinner icon-2x icon-spin"></i>
</div>
</div>
</div>
<div class="container-fluid page-host" data-bind="router: { transition:'entrance' }"></div>
</div>
This is the problem part:
<span data-bind="text: app.user.name()"></span>
user
is a property I add to app
right after it's created. It is updated by the view models for log in and log out.
To get that binding to work I need to bring the object into scope in the view model. Normally I would do that like this: var app = require('durandal/app');
. In most view models this is no problem. But view management gets seriously messed up when I do it in shell.js.
All I'm trying to do is fish out some app state to indicate whether the user is currently logged in.
There are two possible solutions
I'm sure this is trivial to old hands; I await your wisdom. Searching google didn't work well because "app" is way too broad a search term.
I dodged the problem by tacking user onto document instead of app, but that's hideous. I'm all ears for the right way to do this.
Interestingly, HTML5 browsers define sessionStorage
for exactly the purpose to which I polluted document
. If you do this in your boot code
if (typeof(document.sessionStorage) == undefined) document.sessionStorage = {};
then you can assume it exists in the rest of your app. We can't count on browser support, but it's not hard to check and if necessary create it. If you look up sessionStorage you'll see a warning that the contents will be lost at the next page load, but in a SPA that matters not at all.
Upvotes: 1
Views: 128
Reputation:
What we did in our Durandal app is create a separate static module called config
, which contains, among other properties, an observable property called userName
.
At the top of your module (the shell.js file, in this case), put the following:
define([
'durandal/system',
'durandal/activator',
'plugins/router',
'durandal/app',
...
'config'
],
function(system, activator, router, app,..., config) {
}
);
The config
module should be static, which means that it should return an object literal, not a constructor function.
Your config
module might look something like this (bare bones):
define('config', ['knockout'],
function(ko) {
var userName = ko.observable('');
return {
userName: userName
};
}
);
Upvotes: 0
Reputation: 3723
One way to accomplish this (most probably the right one), would be using a shared AMD module as discussed in Session Data with Durandal.
Upvotes: 1