single-page-application - 具有多个 View 的 Durandal 小部件

标签 single-page-application durandal

我正在使用 Durandal 开发一个 SPA,我已经创建了一个用于显示特定页面组件的小部件。关注Durandal Documentation ,widget在app/widgets/my-widget中,由viewmodel.jsview.html组成。

现在,我想向同一个小部件添加不同的 View - 实际上,有一个“基本” View 和一个“高级” View ,并在 ViewModel 中使用一个标志。

我不想创建两个不同的小部件,因为 ViewModel 完全相同,我想避免不必要的代码重复。我也不想将两个版本的 View 都放入 view.html 中,只根据 ViewModel 中的标志显示一个或另一个,因为这将很快成为维护功能的噩梦稍后添加到小部件。

我认为一个答案是做某种 View Composition ,其中要组合的 View 的名称是根据标志从 ViewModel 返回的,但我不太确定该怎么做。

有没有人有办法做到这一点?我应该用不同的方法来解决这个问题吗?


更新 这是我想做的事的一个例子。有一个小部件 workitem 用于显示“工作项”。在 ViewModel 中,工作项有一个属性 status,它可以取值 readyin-progresscomplete,或 无效。根据工作项的状态,需要显示的有关它的信息(及其 View )是完全不同的。我想要做的是设置这样的东西:

-widgets
|
|-workitem
|  |-viewmodel.js
|  |-view-ready.html
|  |-view-in-progress.html
|  |-view-complete.html
|  |-view-invalid.html

...然后根据 ViewModel 中的属性自动选择这些 View 之一。

最佳答案

我们对多 View 小部件采用的方法是简单地使用 ifvisible 绑定(bind),并将其绑定(bind)到持有 View 的 View 模型上的可观察对象类型(例如“紧凑”、“扩展”、“分组”等)。

对于我们的日期选择器小部件,我们的高级 View 是这样的(仅显示其中两个 View ):

</div>
    <div data-bind="visible: viewMode() === 'months'">
        <div data-bind="compose: {model: 'widgets/datepicker/datepickerMonths', view: 'widgets/datepicker/datepickerMonths', activate: true, activationData: messageChannel }">    </div>
    </div>
    <div data-bind="visible: viewMode() === 'years'">
        <div data-bind="compose: {model: 'widgets/datepicker/datepickerYears', view: 'widgets/datepicker/datepickerYears', activate: true, activationData: messageChannel }">    </div>
    </div>
</div>

viewMode observable 允许我们在 View 之间切换。

我们在这种情况下使用visible 绑定(bind)有两个原因:

  1. 性能:布局保持加载到 DOM 中,只是隐藏;
  2. jQuery clickoutside 插件被 if 绑定(bind)搞糊涂了(可以说,if 绑定(bind)将 DOM 从用户鼠标指针下踢出,并导致 clickoutside相信用户点击了外部的插件)。

通过上述方法,您的小部件的单个 view.html 文件可以引用多个可动态组合的 View 。

我提供了一个指向我们日期选择器的公共(public) SkyDrive(现在的 OneDrive)文件夹的链接,该文件夹完全是为了利用 Durandal 的组合和小部件系统以及 KnockoutJS 而编写的:video of datepicker as I switch from one view to another . View 的切换使用上述技术发生。

日期选择器的特点:

  • datepicker 是一个多 View 小部件
  • 它包含一个输入字段和我们的弹出窗口小部件(换句话说,一个小部件内部的小部件)
  • 高级 View 动态组合三个不同的 View ,随着用户交互在它们之间切换
  • 它依赖于 postal.js 作为客户端消息总线,用于在 View 之间路由选择、与父 View 协调以及更新输入控件(如果您愿意,可以使用 Durandal 的内置发布/订阅)
  • 它使用 jwerty.js 进行键盘管理

关于single-page-application - 具有多个 View 的 Durandal 小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18835647/

相关文章:

knockout.js - 从包含 View 模型访问数据

knockout.js - 使用条件逻辑编写 HTML View

javascript - Durandal 中的模块 id 从哪里来?

javascript - Angular 2 get .length 但仅计算 html 或 ts 组件中的特定数据

servicestack - 带有 ServiceStack 的 BreezeJS?

vue.js - 将 Nuxt.js SPA 模式更改为通用模式

asp.net-mvc - 我应该如何保护我的 SPA 和 Web.API?

javascript - 如何使用 jsonp 调用返回的数据在 Durandal 中呈现 View ?

javascript - “类型错误 : undefined is not a function, Durandal SPA

angularjs - 使用 Amazon S3 时如何将爬虫请求重定向到预渲染页面?