Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Durandal: Accessing one view model from another

Using Durandal, I have two view models within my app, let's say vmCompanies & vmEmployees. I have two views, one for each view model and within each, you can see all companies & all employees.

However, when I'm loading my employees, in the DB they have an ID for which company they are employed by. What I'd like to do is the following pseudo:

  • From within the vmEmployees, get a reference to the vmCompanies
  • If the vmCompanies has already been initialized (which I know it is 99% of the time), get a reference to it so I can use something like linq.js to find the specific company this employee works for
  • If the vmCompanies has not been initialized (aka: activated), do so

This way I can avoid the requirement of the vmEmployees having it's own internal cache of companies. So far I've been unable to figure out how in Durandal to query and ask "give me this view model that you've already loaded." It seems like it has that internally because when I navigate between views, they are cached and not reloaded (same with the VMs)... I've just so far been unable to see how I can do it.

like image 409
Andrew Connell Avatar asked Jan 13 '23 16:01

Andrew Connell


1 Answers

You can manually require() a view model by its ____moduleId____. As long as your view model module returns an object and not a function, you'll be dealing with a singleton, so you can be sure you'll get the correct instance.

If you're not sure what the __moduleId__ is, you can use this chrome extension to view your view model's properties, including __moduleId__.

However, instead of manually instantianting VMs, a better alternative may be to create a separate module that you use to store the cached companies. I have a data module with its own internal cache that I use generically for this purpose, but you could create one specifically for companies, and store that information in it. It could even be responsible for loading its own data, if that's appropriate.

Here's some simple code to help explain:

Note this uses the sugar syntax for require JS - if you're using the array-based syntax, you'll need to translate accordingly. I can help if needed.

//companies-cache.js
define(function(require){

    //some auto-loading logic here, if you wish
    var companies = ko.observableArray([]);

    return {
        companies: companies
    };
});

//vmCompanies, vmEmployees
define(function(require){
    var companiesCache = require("viewModels/companies-cache");

    //additional properties for this specific VM
    ...

    return {
        companies: companiesCache.companies
    };
});
like image 92
Joseph Gabriel Avatar answered Mar 16 '23 17:03

Joseph Gabriel