2013-07-15 39 views
7

Tôi vừa mới bắt đầu làm việc với Durandal và tất cả các phần đang rơi vào vị trí, và đang sử dụng mẫu Khăn nóng để tăng tốc độ.Làm cách nào để sử dụng danh sách thả xuống cho điều hướng Durandal?

Có một điều khiến tôi băn khoăn là làm thế nào để tạo ra một hệ thống điều hướng phân cấp phức tạp hơn một nhóm mông. Dưới đây là những gì tôi muốn kết thúc với:

ABC
A1 B1 C1
A2 B2 C2

A, B, và C là các menu cấp cao nhất mà không có các tuyến đường thuộc họ - họ là chỉ cần giữ chỗ. Tôi sẽ có chế độ xem và chế độ xem cho A1, A2, B1, B2, C1 và C2 và cần các thẻ băm đó làm liên kết hoạt động.

Ý tưởng tốt nhất của tôi ngay bây giờ là thêm menu chính vào url của mỗi tuyến đường và có mã trong nav.html tự động thêm từng nút vào phụ huynh thích hợp dựa trên phân tích url. Để có đầy đủ năng động, nó sẽ thêm cả các nút cha và các nút con động.

 { 
      url: 'A_A1', 
      moduleId: 'viewmodels/A_A1', 
      name: 'A1', 
      visible: true 
     } 

Tôi đã làm rất nhiều công tìm kiếm ví dụ chuyển hướng thứ bậc với Durandal nhưng chưa thấy bất cứ điều gì được nêu ra. Có cách nào tốt nhất để mở rộng chức năng điều hướng ngoài danh sách một chiều đơn giản không? Tôi có nhìn thấy một số chức năng trong bộ định tuyến mà tôi không thấy điều đó sẽ cho phép tôi làm điều này mà không cần nhúng thông tin phân cấp vào tên chế độ xem không?

EDIT: Tôi vừa đánh dấu câu trả lời là chính xác, mặc dù tôi không hài lòng với một trong hai giải pháp được trình bày. Khi chọn một khung công tác để trừu tượng và tách biệt logic, trình bày và kiểm soát nó có vẻ ngớ ngẩn để bắt đầu hợp nhất các cấu trúc này một lần nữa chỉ để cung cấp nhiều hơn một trình điều hướng cơ bản. Tôi đã chuyển những nỗ lực phát triển của mình sang angularjs nơi những thứ như thế này trở nên trực quan hơn nhiều và có thể giữ sự tách biệt. Hy vọng rằng Durandal có thể tiến lên một chút trong tương lai gần và tôi chắc chắn sẽ đánh giá lại nó cho các dự án trong tương lai.

Trả lời

6

Bạn có thể mã hóa cứng chúng vào xem shell của bạn, nhưng nếu bạn không muốn làm điều đó bạn có thể làm điều đó đây -

Theo quan điểm của bạn, hãy một tổ chức phi làm việc neo với/# mà không không có gì, với một thả xuống của một tuyến đường, và một với một thả xuống của các tuyến đường b.

 <div class="nav-collapse collapse main-nav"> 
      <div class="btn-group"> 
       <a class="btn" href="/#"> 
        <span class="text">A Routes</span> </a> 
       <button class="btn dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button> 
        <ul class="dropdown-menu pull-right"> 
         <!-- ko foreach: aRoutes --> 
         <li data-bind="css: { active: isActive }"> 
          <a data-bind="attr: { href: hash }, html: name"></a> 
         </li> 
         <!-- /ko --> 
        </ul> 
      </div> 
      <div class="btn-group"> 
       <a class="btn" href="/#"> 
        <span class="text">B Routes</span> </a> 
       <button class="btn dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button> 
        <ul class="dropdown-menu pull-right"> 
         <!-- ko foreach: bRoutes --> 
         <li data-bind="css: { active: isActive }"> 
          <a data-bind="attr: { href: hash }, html: name"></a> 
         </li> 
         <!-- /ko --> 
        </ul> 
      </div> 
     </div> 

Làm cho một số quan sát tính toán cho các tuyến đường theo quan điểm mô hình shell của bạn

var aRoutes = ko.computed(function() { 
     return router.allRoutes().filter(function (r) { 
      return r.settings.aroute; 
     }); 
    }); 

    var bRoutes = ko.computed(function() { 
     return router.allRoutes().filter(function (r) { 
      return r.settings.broute; 
     }); 
    }); 

và trong định nghĩa tuyến đường của bạn -

{ 
    url: 'a1', 
    moduleId: 'viewmodels/a1', 
    name: 'A1', 
    visible: false, 
    settings: {aroute: true} 
}, 

này thiết lập tất cả các tuyến đường của bạn là sai, và sau đó cung cấp cho chúng một thuộc tính khác của aroute được đặt thành true. Các bộ lọc được tính toán chỉ xuống các tuyến với cài đặt đó được đặt thành true.

+0

Đây là một ý tưởng tuyệt vời - gắn thẻ tuyến đường với cha mẹ của nó. Tôi sẽ làm việc này một chút để làm cho nó năng động hơn, và có lẽ thậm chí là một widget Durandal. – Graham

+0

Hy vọng nó sẽ giúp bạn, tôi đã sử dụng phương pháp này trong một thời gian và nó hoạt động thực sự tốt và năng động cùng một lúc. Tôi chỉ thấy tôi đã không có sự chú ý đúng trên các tuyến đường b vì vậy chỉ cần cố định điều đó. Chúc may mắn. –

3

Tôi đã đưa ra giải pháp chung sau khi đọc bài đăng này. Với giải pháp này, bạn có thể tự động thêm bất kỳ tuyến đường nào vào menu thả xuống trong nav.

Trong main.js, trong đó tôi chỉ định các tuyến đường của mình, tôi đã thêm một hàm để ánh xạ đối tượng menu phụ vào đối tượng cài đặt của tuyến đường chính.

function mapSubNav(parentRouteInfo) { 
    var subroutes = []; 
    var length = arguments.length; 
    for (var i = 0; i < length; i++) { 
     subroutes.push(arguments[i]); 
    } 
    parentRouteInfo.settings.subroutes = subroutes; 
} 

var page = router.mapNav('page', null, 'Page'), 
    sub1 = router.mapRoute('page/sub1', null, 'Sub1'), 
    sub2 = router.mapRoute('page/sub2', null, 'Sub2'); 
mapSubNav(nav, sub1, sub2); 

Giải thích:

Chức năng Router mapNav trả về một định nghĩa đường mà trông như thế này:

{ 
    url:'flickr', //you provided this 
    name: 'Flickr', //derived 
    moduleId: 'flickr', //derived 
    caption: 'Flickr', //derived (uses to set the document title) 
    settings: {}, //default, 
    hash: '#/flickr', //calculated 
    visible: true, //from calling mapNav instead of mapRoute 
    isActive: ko.computed //only present on visible routes to track if they are active in the nav 
} 

Chức năng helper, mapSubNav, sẽ đặt một danh sách các tài liệu tham khảo với các tuyến đường bạn muốn xuất hiện trong trình đơn thả xuống trong đối tượng cài đặt. Trong ví dụ này, kết quả sẽ là:

{ 
    url:'page', 
    name: 'Page', 
    moduleId: 'page', 
    caption: 'Page', 
    settings: { subroutes: [nav, sub1, sub2] }, 
    hash: '#/page', 
    visible: true, 
    isActive: ko.computed 
} 

tôi mở rộng viewmodel vỏ của tôi trông như thế này:

define(function (require) { 
    var router = require('durandal/plugins/router'); 
    var app = require('durandal/app'); 

    var ViewModel = function() { 
     var self = this; 
     self.router = router; 
     self.dataToggle = function (route) { 
      return !!route.settings.subroutes ? 'dropdown' : ''; 
     }; 
     self.html = function (route) { 
      return !!route.settings.subroutes ? route.name + ' <b class="caret"></b>' : route.name; 
     }; 
     self.hash = function (route) { 
      return !!route.settings.subroutes ? '#' : route.hash; 
     }; 
     self.divider = function (route, parent) { 
      system.log('Adding', route, 'to dropdown', 'Parent', parent); 
      return route.hash === parent.hash; 
     }; 
     self.activate = function() { 
      return router.activate('welcome'); 
     } 
    }; 

    return new ViewModel(); 
}); 

Lưu ý:

Các chức năng bổ sung trong shell.js sẽ quyết định thuộc tính nào sẽ được thêm vào các phần tử DOM trong nav.


Và cuối cùng, tôi đã chỉnh sửa chế độ xem vỏ của mình trông như thế này;

<div class="nav-collapse collapse"> 
    <ul class="nav navbar-nav" data-bind="foreach: router.visibleRoutes()"> 
     <li data-bind="css: { active: isActive, dropdown: !!settings.subroutes }"> 
      <a data-bind="css: { 'dropdown-toggle': !!settings.subroutes }, 
          attr: { href: $root.hash($data), 'data-toggle': $root.dataToggle($data) }, 
          html: $root.html($data)"></a> 
      <ul data-bind="foreach: settings.subroutes" class="dropdown-menu"> 
       <li><a data-bind="attr: { href: hash }, 
            html: name"></a></li> 
       <li data-bind="css: { divider: $root.divider($data, $parent) }"></li> 
      </ul> 
     </li> 
    </ul> 
</div> 

Kết quả:

Kết quả cuối cùng là một mục trình đơn với một chuyển đổi thả xuống. Trình đơn thả xuống sẽ chứa một liên kết đến phụ huynh và một liên kết đến từng chương trình con. Một cái gì đó như thế này:

--------------------------------------------- 
Menu items... | Page v | More menu items... 
--------------------------------------------- 
       | Page | 
       ---------- 
       | Sub 1 | 
       | Sub 2 | 
       ---------- 

jQuery không cho phép bạn ánh xạ một đường đến một nút thả xuống-Toggle, đó là lý do tôi thực hiện các tuyến đường mẹ giữ một tham chiếu đến chính nó trong danh sách các subroutes Có vẫn sẽ tồn tại một liên kết đến tuyến đường mẹ trong nav.

+0

Điều gì khác với câu trả lời tôi đã cung cấp? –

+0

@PWKad Với giải pháp của tôi, khi mọi thứ đã được thiết lập, bạn có thể tiếp tục sử dụng 'mapSubNav' trong main.js, và menu con sẽ tự động được thêm vào, mà không cần chỉnh sửa bất kỳ tệp nào khác. Tôi không thấy làm thế nào mà có thể đạt được với giải pháp của bạn. Tôi đã bỏ lỡ bất cứ điều gì? –

Các vấn đề liên quan