Durandal 框架的介绍

2022年 6月 2日 54点热度 0人点赞 0条评论





Durandal 是一个轻量级的 JavaScript 框架, 其目标是单页面应用 (SPAs) 的开发变得简单而优雅. 它支持 MVC,MVP 和 MVVM 等模式, 因此不论你采用哪种类型的前端架构,Durandal 都能胜任.

Durandal 以 RequireJS 为基础, 加上一个轻量级的惯例层, 带来了令人惊叹的生产效率, 并且帮助你维持稳健的编码实践. 配上开箱即用的富界面组件, 模态对话框, 事件/消息, 组件, 过渡效果, 导航等等, 使你可以轻松开发出任何你能想象的应用.



我们开始编写 index.html 文件, 内容如下:

<! DOCTYPE html>
    <link rel="stylesheet" href="lib/bootstrap/css/bootstrap.css" />
    <link rel="stylesheet" href="lib/font-awesome/css/font-awesome.css" />
    <link rel="stylesheet" href="lib/durandal/css/durandal.css" />
    <link rel="stylesheet" href="css/starterkit.css" />
    <div id="applicationHost"></div>
    <script src="lib/require/require.js" data-main="app/main"></script>

Durandal 采用 RequireJS 作为其核心构件之一, 鼓励模块化的编程方式. 在 Durandal 应用中, 所有的 JS 代码都写在模块中. 上文 index.html 中的 script 标签就是用于加载 RequireJS 来完成框架的模块策略. 当模块加载器完成初始化后, 它通过 data-main 属性的值来启动应用.

main.js(app 目录)

  paths: {
    'text': '../lib/require/text',
    'plugins' : '../lib/durandal/js/plugins',
    'transitions' : '../lib/durandal/js/transitions',
    'knockout': '../lib/knockout/knockout-3.4.0',
    'jquery': '../lib/jquery/jquery-1.9.1'

define(function (require) {
   var system = require('durandal/system'),
       app = require('durandal/app');


   app.title = 'Durandal Starter Kit';
     dialog: true

   app.start().then(function() {

shell.html (app/views 目录)

  <h2>Hello! What is your name?</h2>
  <form class="form-inline">
       <input type="text" data-bind="value: name, valueUpdate: 'afterkeydown'"/>
       <button type="submit" class="btn" data-bind="click: sayHello, enable: name">Click Me</button>

shell.js(app/viewsmodel 目录)

define(function (require) {
  var app = require('durandal/app'),
      ko = require('knockout');

  return {
     name: ko.observable(),
     sayHello: function() {
       app.showMessage('Hello ' + this.name() + '! Nice to meet you.', 'Greetings');

属性 name 看起来有点特别, 它是我们使用 Knockout 创建的一个可被观察的 (observable) 属性, 可被观察 observable 属性支持数据到 html 的双向绑定, 变更通知和一些其它特性! 现在你可以用 Google 打开 index.html, 或者如果你使用其他浏览器的话, 可以部署到 Web 服务器下然后浏览 index.html. 当页面打开时, 会经历以下这些步骤:

  • 加载 RequireJS.
  • RequireJS 将加载 main.js, 然后配置框架.
  • main.js 调用 setRoot 展示整个应用.
  • 加载 shell.js 和 shell.html, 绑定数据, 然后注入到页面的 applicationHost div 中

页面加载完以后, 试着在输入框中输入点什么, 然后点击按钮看看会有什么效果!

Knockout Binding Handlers

The databinding infrastructure provided by Knockout is very robust. In addition to the built-in bindings, it provides a way to create custom bindings. It's a simple way to encapsulate view-related code, keeping your normal modules free from the ugliness of DOM manipulation. This is the most common mechanism for interacting with the DOM in an application, particularly if the logic is reusable. For example, it's common to wrap jQuery plugins inside of a custom binding handler so they can be declaratively applied to any element. It's extremely efficient as well, since the jQuery plugin will gain access to the element it's declared on and won't need to execute any selectors. Lest you feel that such a mechanism can't be very powerful, it's important to note that Durandal's composition and widget bindings are just custom KO binding handlers. For information on building your own binding handlers, see the Knockout documentation on the subject.

A visit to the KO site or a quick search on github will also help you find many existing community binding handlers which are usable with Durandal. A useful example of what can be done is knockout-delegatedEvents which makes delegated events bindable, without resorting to manual jQuery code.

Delayed Binding Handlers

Sometimes your binding handler needs to work with an element only after it is attached to the DOM and when the entire composition of the view is complete. An example of this is any code that needs to measure the size of an HTML element. Durandal provides a way to register a knockout binding handler so that it does not execute until the composition is complete. To do this, use composition.addBindingHandler. One common use is in focusing elements. Let's re-write Knockout's hasFocus binding so that it is executed after composition is complete. If you have an existing registered binding handler, you can change its execution time simply by doing this:


If you wanted to write a custom binding handler, then provide it as the second argument:




The actual implementation is the same as for Knockout. If you need to return custom binding options from your init, then you can provide a third optional argument, a function which takes the same parameters as init and returns the binding handler options expected by knockout.


使用的是 Knockout 这个组件.

数据的绑定以及事件的绑定都可以通过这个 return 的 object 进行返回.

返回的 vm 的值才可以和页面的数据进行绑定, 其他的都不行.

<button data-bind="click: function () { $parent.selectOption($parent.getButtonValue($data)); }, text: $parent.getButtonText($data), css: $parent.getButtonClass($index)"></button>


vm.eventDescEditable = ko.computed(function () {
    return ! vm.fieldEditableCheck() || ! vm.curRecInfo();


<button data-bind="text:i18n.textRegBtnSupply,click:onSupply,visible:! eventDescEditable()"></button>

有个问题, 这里也没有 type=button 啊, 为啥就绑定了 click 事件? 费解!


// 设置 div 中的内容
app.setRoot("view/sms/modules/unitchooser", null, "mis-shortmessage-send-unit-chooser-pane-wrapper");


好像没啥总结, 直接找个模板抄一下就可了, 有啥问题再继续记录吧.




本文链接地址:Durandal 框架的介绍,英雄不问来路,转载请注明出处,谢谢。