我已经开始使用Durandal(作为,几个小时前),希望管理视图并允许在单个页面内进行组合-之前的方法,也使用Knockout,对于在一个大的HTML文件中维护来说太笨拙了。
我已经安装/设置Durandal和我可以创建视图和视图模型-然而,我不知道如何获得数据进入视图模型使用作为基础为新的视图模型。
例如,我有一个用于选择项目的"左导航栏"——当一个项目被选中时,它会在当前模型中更新一个"选中的项目"可观察对象,但它也应该加载右边正确的"细节视图":因为尝试Durandal分离组件/视图的部分原因,这应该来自一个单独的视图/视图模型。
我已经阅读了包括组合和使用组合在内的文档,但是关于如何将数据传递给视图模型的方法对我来说并不清楚。似乎我可以使用一个视图与现有的模型(在当前视图/范围),但我真的很想仅仅使用一些当前模型数据(即id)来获取视图中的"真实"模型数据。
因此,我的问题;
-
如何传递初始数据,例如"选定项"到视图模型处理?我更倾向于使用声明性的"compose:"绑定,因为这是使KO…KO。
-
这种拥有/传递初始数据的概念在这里是正确的方式,还是有更好的替代方法?我看到"activeItem"被模糊地提到,但细节/使用暗示我。
更新1:我发现了我们如何在视图之间共享数据/将数据视图传递给视图,但实际实现中缺乏响应。我真的不想在父子(不同的视图/视图模型对)之间共享视图模型,我想使用声明性方法(没有事件)。父节点不需要知道子节点,但是子节点需要从父节点获取数据。
更新2:虽然上面我暗示只需要"id",但我想要一种方法,可以与任何基础对象一起工作,路由器不一定适合。在这种情况下,不需要考虑深度链接。但是,如果你觉得路由器是解决这个问题的方式,请发表一个这样的参数(带详细信息)作为答案,我至少会给它一个投票。
如果您查看breeze源代码,您可以看到一个主-细节方法的示例。
他们正在使用一个激活器来组合子视图。
https://github.com/IdeaBlade/Breeze/blob/master/Samples/TempHire/TempHire/App/viewmodels/resourcemgt.js我不知道您是否在使用breeze,但是这种方法与您如何获得数据无关。
Eric Panorel在这里有一篇关于如何使用John Papa的Visual Studio SPA模板来实现这一点的很棒的文章: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>
现在,剩下的就是使用route data参数在detail视图模型中拉出ID, 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');
});
});
好了!
我认为这是可能的传递任何基础对象,因为我们做模态调用。ko.compose
是被动的;有了durandal路由器,你可以把你的数据带到你喜欢的地方。看看我的解决方法在这个答案和帮助执行。