简体   繁体   中英

Can't require('durandal/app') in shell.js

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

  • Get app into scope somehow
  • Manage application state in some other way that is in scope in shell.js

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.

实现此目标的一种方法(最有可能是正确的方法)是使用与Durandal的Session Data中讨论的共享AMD模块。

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
        };
    }
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM