Как передать данные (выбранный элемент) в детальное представление Дюрандаля?

Я начал использовать (по состоянию на несколько часов назад) Durandal в надежде управлять представлениями и разрешать композицию в пределах одного page — предыдущий подход, также использующий Knockout, становился слишком громоздким, чтобы поддерживать его в толстом HTML-файле.

Я установил/настроил Durandal и могу создавать представления и модели представления, однако я не знаю, как получить данные в модель представления для использования в качестве основы для новая модель просмотра.

Например, у меня есть «левая панель навигации» для выбора элементов — когда элемент выбран, он обновляет «выбранный элемент», наблюдаемый в текущей модели, но он должен также загружать правильный «детальный вид». " справа: поскольку одна из причин попробовать Durandal разделить компоненты/представления, это должно исходить из отдельного представления/модели представления.

Я прочитал всю документацию, включая Composition и Использование композиции, но метод как передавать данные в модель представления мне не ясен. Кажется, я мог бы использовать представление с существующей моделью (в текущем представлении/области), но мне бы очень хотелось просто использовать некоторые данные текущей модели (т.е. идентификатор) для получения «настоящих» данных модели в вид.

Таким образом, мои вопросы;

  • Как обрабатывается передача исходных данных, таких как «выбранный элемент», в модель представления? Я бы предпочел использовать декларативную привязку «compose:», так как это делает KO .. KO.

  • Является ли это понятие наличия/передачи исходных данных правильным способом или есть лучшая альтернатива? Я видел неопределенное упоминание «activeItem», но подробности/использование ускользают от меня.


Обновление 1: я нашел Как мы обмениваемся данными между представлениями/пропусками представление данных для просмотра, но ответы отсутствуют в фактической реализации. Мне бы очень не хотелось делиться моделью представления между родителем и дочерним элементом (разные пары представление/модель представления), и я хотел бы использовать декларативный подход (без событий). Родитель не должен знать о дочернем элементе, но дочерний элемент должен получать данные от родителя.


Обновление 2: Хотя выше я намекнул, что требуется только «id», мне нужен подход, который работает с любым базовым объектом, для которого маршрутизатор не обязательно подходит. Глубокие ссылки в данном случае не важны. Однако, если вы считаете, что маршрутизатор - это способ подойти к этому, опубликуйте аргумент для такого (с подробностями) в качестве ответа, и я, по крайней мере, проголосую за него..


person Community    schedule 10.03.2013    source источник


Ответы (3)


Если вы посмотрите на исходный код бриза, вы увидите пример подхода master-detail.

Они используют активатор для создания дочернего представления.

https://github.com/IdeaBlade/Breeze/blob/master/Samples/TempHire/TempHire/App/viewmodels/resourcemgt.js

Я не знаю, используете ли вы ветер или нет, но подход не зависит от того, как вы получаете данные.

person Julián Yuste    schedule 11.03.2013
comment
В итоге я использовал этот подход, и он работает, но было бы очень хорошо, если бы compose: мог пройти activationData, аналогично modalDialog.show(id, activationData) (без взлома ядра).. - person ; 13.03.2013
comment
Недавно в композицию была добавлена ​​функция activationData. Я полагаю, что он передается методу activate viewModel. - person neverfox; 02.06.2013

Существует отличная статья Эрика Панореля о том, как это сделать с помощью шаблона SPA Джона Папы для Visual Studio: http://ericpanorel.net/blog/hot-towel-spa-master-detail-scenario.

Короче говоря, вы можете воспользоваться преимуществами маршрутизации в Durandal, и это будет выглядеть примерно так:

master.js предоставит набор элементов:

define(function() {
  var self = this;

  this.items = ko.observableArray([]);

  var activate = function() {
     // ... get your items
     self.items([ { id: 0, name: 'Item 1' }, { id: 1, name: 'Item 2' }]);
  }

  return {
    // some properties and ...
    activate: activate
  }
});

master.html свяжет их и свяжет с детальным просмотром:

<section data-bind="foreach: items">
   <a data-bind="text: name, attr: { href: '#/item/' + id() }"></a>
</section>

Теперь все, что осталось, это использовать параметр данных маршрута, чтобы вытащить идентификатор в подробной модели просмотра, detail.js:

define(function() {
  var self = this;

  this.name = ko.observable();

  var activate = function(routeData) {
     var itemId = routeData.id;

     // ... get your item details
     // var details = ...

     self.name(details.name);
  }

  return {
    // some properties and ...
    activate: activate
  }
});

Наконец, вам нужно будет указать маршрут в вашем main.js:

define(['durandal/app', 'durandal/viewLocator', 'durandal/system', 'durandal/plugins/router'],
function(app, viewLocator, system, router) {

    //>>excludeStart("build", true);
    system.debug(true);
    //>>excludeEnd("build");

    app.title = 'Durandal app';
    app.start().then(function() {
        toastr.options.positionClass = 'toast-bottom-right';
        toastr.options.backgroundpositionClass = 'toast-bottom-right';

        //Replace 'viewmodels' in the moduleId with 'views' to locate the view.
        //Look for partial views in a 'views' folder in the root.
        viewLocator.useConvention();

        //configure routing
        router.useConvention();
        router.mapRoute('item/:id', 'viewmodels/item', 'Item', false);

        app.adaptToDevice();

        //Show the app by setting the root view model for our application with a transition.
        app.setRoot('viewmodels/shell', 'entrance');
    });
});

И вот!

person Michael Teper    schedule 04.05.2013

Я думаю, что можно передать любой базовый объект, как мы это делаем с модальным вызовом. ko.compose пассивен; с маршрутизатором Durandal вы можете передавать свои данные куда угодно. Взгляните на мой обходной путь в этом ответе и помогите выполнить.

person M.Ouedraogo    schedule 10.05.2013