2
votes

I have a pretty simple thing I want to accomplish but I cannot figure out how or if it is even possible. I am using the Hot Towel template to start with. In the shell viewmodel I have a user observable. I would like to be able to reference that user observable from other pages on my site. For example from the home page. I tried a couple of things but it doenst appear as though I can access the shell from the composed view. I have a working solution at the moment that uses event pub/sub calls from the shell to pass the user data to anyone listening whenever the data changes (home view in this example). This works it just seems a little clunky and not really the ideal way to handle this. This user observable will need to be used all throughout the site to determine when certain features should be available and to show a particular users projects.

Is there a way to data bind to a knockout observable contained in the shell viewmodel from the home view?

3

3 Answers

4
votes

You might consider having a global.js that returns a singleton, which you include in view models as needed.

define(function () {

    return {
        sharedObservable: ko.observable(),
        sharedObservableArray: ko.observableArray(),
        ...
    };
});

Using global in a viewmodel.

define([..., global], function (..., global) {
    ...
    global.sharedObservable('updated');

    // As an alternative use a local var for easier access
    // var localVar = global.sharedObservable;
    // localVar('updated') 
    ...

});
0
votes

The easiest way is to import the shell module into your viewmodel with requirejs and then expose the shell viewmodel as a variable on the module's viewmodel.

Somehting like this:

// Some viewmodel
define(['shell'], function(shell){
     var vm = {
         shell: shell,
         ...
     };
     return vm;
});

Then in your view, you can bind using $root.shell

<span data-bind="text: $root.shell.shellObservable"></span>
0
votes

Non of previous answers worked for me. Thus, I tried another variant of access to shell and it made the job done.

I've got this in my shell.js:

    define(['plugins/router', 'durandal/app'], function (router, app) {
      return {
        // I need an access to this array in my view
        breadcrumbs: ko.observableArray([]), 
        ...
        };
   });

And this in my view:

define(function () {
    var ctor = function () {
        this.pageTitle = 'Preview';
        this.activate = function () {
            require('viewmodels/shell').breadcrumbs([...]);
        };
    };
    return ctor;
});

So, require('viewmodels/shell') actually returns reference to a shell object.