Дюрандаль: доступ к одной модели представления из другой

Используя Durandal, у меня есть две модели представления в моем приложении, скажем, vmCompanies и vmEmployees. У меня есть два представления, по одному для каждой модели представления, и в каждом из них вы можете видеть все компании и всех сотрудников.

Однако, когда я загружаю своих сотрудников, в БД у них есть идентификатор, в какой компании они работают. Я хотел бы сделать следующее псевдо:

  • Из vmEmployees получите ссылку на vmCompanies
  • Если vmCompanies уже инициализирован (я знаю, что это 99% времени), получите ссылку на него, чтобы я мог использовать что-то вроде linq.js, чтобы найти конкретную компанию, в которой работает этот сотрудник.
  • Если vmCompanies не была инициализирована (она же: активирована), сделайте это

Таким образом, я могу избежать требования, чтобы у vmEmployees был собственный внутренний кеш компаний. До сих пор я не мог понять, как в Durandal запрашивать и спрашивать «дайте мне эту модель представления, которую вы уже загрузили». Похоже, что у него это есть внутри, потому что, когда я перемещаюсь между представлениями, они кэшируются и не перезагружаются (то же самое с виртуальными машинами)... Я просто пока не смог понять, как я могу это сделать Это.


person Andrew Connell    schedule 12.04.2013    source источник


Ответы (1)


Вы можете вручную require() представить модель по ее ____moduleId____. Пока ваш модуль модели представления возвращает объект, а не функцию, вы будете иметь дело с синглтоном, поэтому можете быть уверены, что получите правильный экземпляр.

Если вы не уверены, что такое __moduleId__, вы можете использовать это расширение Chrome для просмотра свойств вашей модели представления, включая __moduleId__.

Однако вместо того, чтобы вручную создавать экземпляры виртуальных машин, лучшей альтернативой может быть создание отдельного модуля, который вы используете для хранения кэшированных компаний. У меня есть модуль данных с собственным внутренним кешем, который я обычно использую для этой цели, но вы можете создать его специально для компаний и хранить в нем эту информацию. Он может даже отвечать за загрузку собственных данных, если это уместно.

Вот простой код, который поможет объяснить:

Обратите внимание, что здесь используется синтаксис сахара для require JS. Если вы используете синтаксис на основе массива, вам нужно будет соответствующим образом перевести. Я могу помочь, если нужно.

//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
    };
});
person Joseph Gabriel    schedule 13.04.2013
comment
Немного поиграл и понравился такой подход. Я следую шаблону, в котором у меня есть модель оболочки, в которой размещается приложение. Итак, я думаю, что могу поместить кэшированные объекты в эту модель и из каждой модели представления, просто используйте require(), чтобы получить ссылку на этот всегда загруженный модуль и просто получить доступ/изменить свойства этого. Я пытался использовать отдельную модель кеша, но только одно из моих представлений могло ее увидеть... - person Andrew Connell; 13.04.2013
comment
вы можете взглянуть на breezeJS, если вы еще этого не сделали. Он имеет хорошую поддержку кэширования. - person Joseph Gabriel; 19.04.2013
comment
BreezeJS не является для меня очевидным вариантом, так как в моей ситуации (SharePoint 2013) я не могу поместить в коробку какой-либо серверный код. Я могу использовать только существующую библиотеку (JavaScript OM на стороне клиента) и сервисы OOTB REST. - person Andrew Connell; 20.04.2013
comment
@AndrewConnell Из документации BreezeJS кажется, что BreezeJS может работать без изменений на стороне сервера. См. этот пример (breezejs.com/samples/edmunds) для вдохновения. - person KMeda; 03.06.2013