gpt4 book ai didi

durandal - 使用 DurandalJS 为同一个模块构建多个导航路径

转载 作者:行者123 更新时间:2023-12-02 03:34:49 25 4
gpt4 key购买 nike

我真的很想利用 Durandal 的 buildNavigationModel() 方法并将我的 UI 导航绑定(bind)到 router.navigationModel

但就我而言,我基本上想要三个菜单项,它们都使用相同的底层 View 和模块,但仅参数不同。

    // . . . 

activate: function () {
var standardRoutes = [
{ route: 'home', title: 'KPI Home', iconClass: "glyphicon-home", moduleId: 'viewmodels/kpihome', nav: true },
{ route: 'summary(/:category)', title: 'Quotes', iconClass: "glyphicon-home", moduleId: 'viewmodels/summary', hash: "#summary/quotes", nav: true },
{ route: 'summary(/:category)', title: 'Pricing', iconClass: "glyphicon-home", moduleId: 'viewmodels/summary', hash: "#summary/pricing", nav: true },
{ route: 'summary(/:category)', title: 'Sales', iconClass: "glyphicon-home", moduleId: 'viewmodels/summary', hash: "#summary/sales", nav: true }
];

router
.map(standardRoutes)
.buildNavigationModel();

return router.activate();
}

因此,虽然哈希值不同,而且我可以选择传递给摘要模块的 activate 方法的类别,但当我单击其他任何一条路由时,第一个匹配的路由 isActive 标记为真。换句话说,isActive 处理路由模式而不是精确的哈希比较。

谁能推荐一种替代/最佳实践方法来解决这个问题,我可以在其中重复使用路线模式和模块并且仍然有一个可用的导航?

我目前的解决方案是只创建一次路线并构建我自己的导航模型。

最佳答案

经过一番挖掘,我找到了解决此问题的三种可能方法。

  1. 使用子路由器
  2. 在路由中使用自定义标识符来描述子路由并将其解析到路由表中
  3. 将路由留给路由表并创建自定义导航模型

我将在下面谈谈我对每个问题的看法以及我是如何找到解决方案的。以下帖子对我帮助很大Durandal 2.0 - Child routers intended for nested menus?

使用子路由器

虽然当您想创建存在于主路由器提供的 View 中的子路由时这很有意义,但我的要求是在包含所有子路由的 shell 级别上显示导航,始终可见和加载.

根据 the article mentioned above

"if we check the code of function creating child routes we will see that it creates new router and only store reference to parent router - the parent router ( in most cases main router) does not have references to its childs"

所以我的决定是基于此(希望是正确的信息)并且对于我的案例来说它看起来行不通。

在路由中使用自定义标识符来描述子路由并将其解析到路由表中

这有效并在 the article mentioned above 中巧妙地实现了.但是路由表有没有和UI导航一样的顾虑呢?在某些情况下,确定它可以共享,但在我的情况下不能,所以我选择选项 3,创建自定义导航模型。

创建自定义导航模型

我需要为导航项目重新使用一些 View ,以显示相同的摘要和详细 View ,但对于不同的类别和我将通过参数传入的 kpi。

从路由表的角度来看,只有三个路由 - 到主页 View 、摘要 View 和详细 View 的路由。

从导航的角度来看,有 n 个导航项,具体取决于类别的数量和我要为其显示摘要和详细 View 的 kpi。我会有效地为我想展示的所有项目设置链接。

因此,我独立于路由表构建导航模型是有道理的。

utility\navigationModel.js

定义导航模型并响应哈希更改以在 activeHash 可观察对象中保留记录

define(["knockout", "utility/navigationItem"], function (ko, NavItem) {
var NavigationModel = function () {
this.navItems = ko.observableArray();
this.activeHash = ko.observable();

window.addEventListener("hashchange", this.onHashChange.bind(this), false);

this.onHashChange();
};

NavigationModel.prototype.generateItemUid = function () {
return "item" + (this.navItems().length + 1);
};

NavigationModel.prototype.onHashChange = function () {
this.activeHash(window.location.hash);
};

NavigationModel.prototype.findItem = function (uid) {
var i = 0,
currentNavItem,
findRecursive = function (uid, base) {
var match = undefined,
i = 0,
childItems = base.navItems && base.navItems();

if (base._uid && base._uid === uid) {
match = base;
} else {
for (; childItems && i < childItems.length; i = i + 1) {
match = findRecursive(uid, childItems[i]);
if (match) {
break;
}
}
}

return match;
};

return findRecursive(uid, this);
};

NavigationModel.prototype.addNavigationItem = function (navItem) {
var parent;

if (navItem.parentUid) {
parent = this.findItem(navItem.parentUid);
} else {
parent = this;
}

if (parent) {
parent.navItems.push(new NavItem(this, navItem));
}

return this;
};

return NavigationModel;
});

utility\navigationItem.js

代表导航项,具有导航特定属性,如 iconClass、子导航项 navItems 和用于确定它是否为事件导航的计算 isActive

define(["knockout"], function (ko) {
var NavigationItem = function (model, navItem) {
this._parentModel = model;

this._uid = navItem.uid || model.generateItemUid();
this.hash = navItem.hash;
this.title = navItem.title;
this.iconClass = navItem.iconClass;

this.navItems = ko.observableArray();

this.isActive = ko.computed(function () {
return this._parentModel.activeHash() === this.hash;
}, this);
}

return NavigationItem;
});

shell.js

为路由表定义标准路由并构建自定义导航。如果实现得当,这可能会调用数据服务来查找导航模型的类别和 kpi

define([
'plugins/router',
'durandal/app',
'utility/navigationModel'
], function (router, app, NavigationModel) {

var customNavigationModel = new NavigationModel(),

activate = function () {
// note : routes are required for Durandal to function, but for hierarchical navigation it was
// easier to develop a custom navigation model than to use the Durandal router's buildNavigationModel() method
// so all routes below are "nav false".
var standardRoutes = [
{ route: '', moduleId: 'viewmodels/kpihome', nav: false },
{ route: 'summary(/:category)', moduleId: 'viewmodels/summary', hash: "#summary/quotes", nav: false },
{ route: 'kpidetails(/:kpiName)', moduleId: 'viewmodels/kpidetails', hash: "#kpidetails/quotedGMPercentage", nav: false }
];

router.map(standardRoutes);

// Fixed items can be added to the Nav Model
customNavigationModel
.addNavigationItem({ title: "KPI Home", hash: "", iconClass: "glyphicon-home" });

// items by category could be looked up in a database
customNavigationModel
.addNavigationItem({ uid: "quotes", title: "Quotes", hash: "#summary/quotes", iconClass: "glyphicon-home" })
.addNavigationItem({ uid: "sales", title: "Sales", hash: "#summary/sales", iconClass: "glyphicon-home" });

// and each category's measures/KPIs could also be looked up in a database and added
customNavigationModel
.addNavigationItem({ parentUid: "quotes", title: "1. Quoted Price", iconClass: "glyphicon-stats", hash: "#kpidetails/quotedPrice" })
.addNavigationItem({ parentUid: "quotes", title: "2. Quoted GM%", iconClass: "glyphicon-stats", hash: "#kpidetails/quotedGMPercentage" });

customNavigationModel
.addNavigationItem({ parentUid: "sales", title: "1. Quoted Win Rate", iconClass: "glyphicon-stats", hash: "#kpidetails/quoteWinRate" })
.addNavigationItem({ parentUid: "sales", title: "2. Tender Win Rate ", iconClass: "glyphicon-stats", hash: "#kpidetails/tenderWinRate" });

return router.activate();
};

return {
router: router,
activate: activate,
customNavigationModel: customNavigationModel
};
});

就是这样,相当多的代码,但是一旦就位,它就可以很好地将路由表和导航模型分开。剩下的就是将它绑定(bind)到 UI,我使用一个小部件来完成,因为它可以用作递归模板。

widgets\verticalNav\view.html

<ul class="nav nav-pills nav-stacked" data-bind="css: { 'nav-submenu' : settings.isSubMenu }, foreach: settings.navItems">
<li data-bind="css: { active: isActive() }">
<a data-bind="attr: { href: hash }">
<span class="glyphicon" data-bind="css: iconClass"></span>
<span data-bind="html: title"></span>
</a>

<div data-bind="widget: {
kind: 'verticalNav',
navItems: navItems,
isSubMenu: true
}">
</div>
</li>
</ul>

我并不是说这是最好的方法,但如果您想分离路由表和导航模型的关注点,这是一个潜在的解决方案:)

关于durandal - 使用 DurandalJS 为同一个模块构建多个导航路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24241162/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com