2015-08-25 2 views
2

Я пытаюсь создать многоуровневое меню. Меню должно содержать как один уровень, так и один уровень в двух уровнях и три уровня. Разделы не могут быть размещены подряд. Пример меню: This is example menu, which I needВыпадающее меню в Durandal 2.0

Я написал группе Google DurandalJS, но никто не объяснил, что я делаю неправильно. Я нашел это example, но я не работаю.

Обращение к людям, которые понимают такие вещи: 1. Как организовать логику этого меню. 2. Как привязать данные к виду 3. Нужно ли использовать для этого ChildRouter?

Я надеюсь на помощь.

ответ

1

ОК, поэтому этот ответ в основном является модификацией previous routing answer, позволяя на этот раз несколько уровней (вопрос о трех уровнях, но я дам общий ответ для любого количества уровней).

Модель

Как и в моем предыдущем ответе, я не буду использовать дочерние маршрутизаторы Дюрандаль (причины, указанные в описании сцепленных ранее ответа). Вместо этого будет предоставлен мой собственный способ определения «встроенных» маршрутов.

Давайте предположим, имеющие следующие моделями

var model = [ 
       { 
        route: '', 
        moduleId: 'viewmodels/home', 
        title: 'Validation test', 
        nav: true, 
        hash: '' 
       }, 
       { 
        route: 'samples', 
        moduleId: 'viewmodels/samples', 
        moduleRootId: 'viewmodels', // Custom property to make child routes easier    
        title: 'Samples', 
        nav: true, 
        hash: 'samples', 
        childRoutes: [ 
         { route: 'simpleList', moduleId: 'simpleList', title: 'SimpleList', nav: true, hash : 'simpleList', childRoutes: [ 
          { route: 'simpleListA', moduleId: 'simpleListA', title: 'SimpleListA', nav: true, hash : 'simpleListA' }, 
          { route: 'simpleListB', moduleId: 'simpleListB', title: 'SimpleListB', nav: true, hash : 'simpleListB' } ] }, 
         { route: 'clickCounter', moduleId: 'clickCounter', title: 'Click Counter', nav: true, hash : 'clickCounter' } 
        ] 
       } 
      ]; 

У нас есть два 0-уровня (верхний уровень) маршрутов (Home и образцы), два 1-уровня (Чайлдс выборки - SimpleList и ClickCounter) и два 2- уровень (дочерние элементы SimpleList - SimpleListA и SimpleListB).

Трансформация

Что Durandal ожидает, чтобы это просто список маршрутов. Поэтому нам нужно преобразовать нашу красивую структуру модели в список маршрутов (с некоторыми изменениями в hash, moduleId [Я предполагаю, что структура папки viewModel такая же, как и наши маршруты, т. Е. Модели просмотра SimpleList и ClickCounter находятся в подпапках, то же самое для SimpleListA и SimpleListB])

Алгоритм - это в основном траверс и выравнивание дерева.

function flatRoutes (routes, level, path, parent) { 
    var output = [] 
    $.each(routes, function(index, route) { 
     route.route = path + route.route; 
     route.moduleId = path + route.moduleId; 
     route.hash = '#' + path + route.hash; 
     route.parent = parent; 
     route.level = level; 
    output = output.concat(route) 
    if (route.childRoutes !== undefined) output = output.concat(flatRoutes(route.childRoutes, level + 1, route.route + '/', route.route)) 
    }) 
    return output; 
    } 

function createRoutes (routes) { 
    return flatRoutes(routes, 0, '', '') 

} 

Как всегда маршруты должны быть зарегистрированы и маршрутизатор активирован:

var routes = createRoutes(model); 
return router.map(routes) 
      .buildNavigationModel() 
      .activate(); 

Rendering

К сожалению, эта часть не проверяется, как я не использую Дюрандаль/стек Нокаут больше.

В ShellVM (или где-то еще вы хотите связать маршрутизатор с нокаутом) вам понадобится функция поиска дочерних маршрутов для данного родителя.

function findRoutes (parent) { 
    var output = [] 
    $.each(router.navigationModel, function(index, route) { 
     if(route.paent === parent) output = output.concat(route) 
    } 
    return output; 
} 

А в разделе «Нокаут/HTML» вам нужно будет использовать рекурсивные шаблоны для нокаута.

<script id="treeElement" type="text/html"> 
    <li> 
     <span data-bind="text: title"></span> 
     <ul data-bind="template: { name: 'treeElement', foreach: $root.vm.findRoutes($data.moduleId) }"> 
     </ul> 
    </li> 
</script>  

<ul data-bind="template: { name: 'treeElement', foreach: $root.vm.findRoutes('') }"></ul> 

Конечно, это просто оказывающего маршрутизатор в качестве простого списка mulitlevel - Вам нужно будет изменить его в соответствии с тем, что вы хотите достичь, и какие CSS рамки вы используете. Но это должно быть легко.

+0

Извините, но вы можете дать мне пример проекта? У меня много ошибок в проекте. Значение привязки: template: {name: 'treeElement', foreach: $ root.vm.findRoutes ('')} Возможно, вы можете указать URL-адрес в GitHub или аналогичном сервере? Невозможно проанализировать привязки. Сообщение: $ root.vm не определено; –

Смежные вопросы