纯粹与UI相关的javascript在Durandal视图中的位置在哪里?

时间:2013-05-16 17:37:13

标签: javascript single-page-application durandal

我正在使用基于Durandal的SPA,并遵循他们的'views'和'viewmodels'的惯例,基本功能正常。即使用somepage.html& somepage.js

然而,当添加更多交互式UI元素(例如可折叠的手风琴或信息弹出窗口)时,处理这些事件的javascript应该放在哪里?把它放在somepage.js viewmodel文件中并没有'闻到' - 那是... 视图模型

从最佳实践角度来看,在我的somepage.html文件中设置脚本块会更好吗? E.g。

<section>
    <!- html markup and data-binding goes here>
</section>

<script type="text/javascript">
    <!-- UI-only Javascript goes here>
</script>

或者有更好的方法吗?

3 个答案:

答案 0 :(得分:3)

您的纯GUI javascript元素应该通过html数据属性绑定到UI。例如,bootstrap accordian将具有以下html (Bootstrap Documentation here)

<div class="accordion" id="accordion2">
  <div class="accordion-group">
    <div class="accordion-heading">
      <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#collapseOne">
        Collapsible Group Item #1
      </a>
    </div>
    <div id="collapseOne" class="accordion-body collapse in">
      <div class="accordion-inner">
        Anim pariatur cliche...
      </div>
    </div>
  </div>
.......

并在页面底部引用了您的引导程序javascript文件。

答案 1 :(得分:3)

我也一直在努力解决这个问题,我同意在viewModel中添加与视图相关的内容。我需要做的事情的原因是attach a delegated event handler - 这是使用自定义绑定或小部件无法完成的。

我和同事提出的最佳解决方案是从viewModel传播viewAttached事件,并在“视图文件”中侦听事件。

使用名为“awesome”的视图作为示例,我们使用这样的命名约定:

  • 查看模型 - viewmodels / awesome.js
  • 查看 - views / awesome.html
  • 查看文件 - views / awesome.html.js

以下是我们正在做的简化版本。

<强>的ViewModels / awesome.js:

define([
    "durandal/app",
    "durandal/system",

    // require the view file; note we don't need a reference to it,
    // we just need to make sure it's loaded
    "views/myView.html"
],

function (app, sys) {
    var viewModel = {
        // whatever
    };

    viewModel.viewAttached = function(view) {
        // Create a namespace for the event
        var eventNamespace = sys.getModuleId(viewModel)
            .replace("viewmodels", "")
            .replace("/", ".");

        // This will evaluate to 'awesome.viewAttached'
        var eventName = eventNamespace + ".viewAttached";

        // Trigger the event and pass the viewModel and the view
        app.trigger(eventName, viewModel, view);
    };

    return viewModel;
});

<强>视图/ awesome.html.js:

define([
    "durandal/app"
],

function (app) {
    var module = {
        viewAttached: function(viewModel, view) {
            // do your thing! make sure any selectors you use use the view as the parent selector,
            // because you're not guaranteed that your view is in the DOM (only that it's attached
            // to its parent).
            var $submit = $("#submit", view);
        }
    };

    // wire-up
    app.on("awesome.viewAttached", module.viewAttached);

    // export
    return module;
});

希望有所帮助。

答案 2 :(得分:1)

viewAttached是一个非常危险的小东西......它很容易将所有JS代码放在那里......但它并不理想。我发现的一个小怪癖是在嵌套视图模型中

父 第1步(孩子1) 第2步(孩子2)

父母切换(child1&lt; - &gt; child2)

如果父级操作子视图(从子级1切换到子级2),则viewAttached将无法在子级上正常触发(此时DOM尚未可用)并且父级已经附加了它不要在父亲身上运行viewAttached!

所以你突然发现所有的JS模块都会停止工作,然后你必须为需要外部JS修改的元素做ko customBindings。