9

我已经开始使用(从几个小时前开始)Durandal,希望能够管理视图并允许在单个页面中进行组合 - 以前的方法(也使用 Knockout)变得过于笨拙,无法在胖 HTML 文件中维护。

我已经安装/设置了 Durandal,并且可以创建视图和视图模型 - 但是,我不知道如何将数据导入视图模型以用作新视图模型的基础

例如,我有一个用于选择项目的“左侧导航栏”——当一个项目被选中时,它会更新当前模型中可观察到的“选定项目”,但它也应该右侧加载正确的“详细视图”:因为部分尝试 Durandal 分离组件/视图的原因,这应该来自单独的视图/视图模型。

我已经阅读了包括CompositionUsing Composition的文档,但是关于如何将数据传递给 viewmodel 的方法对我来说并不清楚。似乎我可以使用具有现有模型的视图(在当前视图/范围内),但我真的很想只使用一些当前模型数据(即 id)来获取“真实”模型数据风景。

因此,我的问题;

  • 如何将初始数据(例如“选定项目”)传递给视图模型?我更喜欢使用声明性的“compose:”绑定,因为这就是 KO .. KO 的原因。

  • 这种拥有/传递初始数据的概念在这里是正确的方式,还是有更好的选择?我已经看到模糊地提到了“activeItem”,但细节/用途却让我印象深刻。


更新 1:我发现了 How do we share the data between views/Pass the data view to view,但在实际实现中缺乏响应。我真的不想在父子之间共享视图模型(不同的视图/视图模型对),我想使用声明性方法(无事件)。父母不需要知道孩子,但孩子需要从父母那里得到数据。


更新2:虽然上面我暗示只需要“id”,但我想要一种适用于任何基础对象的方法,路由器不一定适合。在这种情况下,深度链接不是问题。但是,如果您认为路由器是解决此问题的方法,请发布此类(带有详细信息)的论点作为答案,我至少会给它一个赞成票..

4

3 回答 3

3

如果您查看微风源代码,您可以看到一个主从方法的示例。

他们正在使用激活器来组成子视图。

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

我不知道您是否正在使用微风,但该方法与您如何获取数据无关。

于 2013-03-11T11:19:58.320 回答
3

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>

现在,剩下的就是使用路由数据参数在详细视图模型中提取 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');
    });
});

你去吧!

于 2013-05-04T06:10:28.687 回答
0

我认为可以像使用模态调用一样传递任何基础对象。ko.compose是被动的;使用 durandal 路由器,您可以将数据传输到您喜欢的地方。看看我在这个答案中的解决方法并帮助执行。

于 2013-05-10T00:02:59.800 回答