在Durandal视图中,纯粹与UI相关的javascript将走向何方?

在Durandal视图中,纯粹与UI相关的javascript将走向何方?,javascript,single-page-application,durandal,Javascript,Single Page Application,Durandal,我正在玩一个基于Durandal的水疗中心,按照他们拥有“视图”和“视图模型”的惯例,基本功能运行良好。即使用somepage.html&somepage.js 但是,当添加更多交互式UI元素(例如,可折叠的手风琴或信息性弹出窗口)时,处理这些事件的javascript应该放在哪里?把它放在somepage.jsviewmodel文件中是不对的-那是为了。。。查看模型 从最佳实践的角度来看,在我的somepage.html文件中有一个脚本块会更好吗?例如 <section>

我正在玩一个基于Durandal的水疗中心,按照他们拥有“视图”和“视图模型”的惯例,基本功能运行良好。即使用
somepage.html
&
somepage.js

但是,当添加更多交互式UI元素(例如,可折叠的手风琴或信息性弹出窗口)时,处理这些事件的javascript应该放在哪里?把它放在
somepage.js
viewmodel文件中是不对的-那是为了。。。查看模型

从最佳实践的角度来看,在我的
somepage.html
文件中有一个脚本块会更好吗?例如

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

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


纯GUI javascript元素应该通过html数据属性绑定到UI。例如,一个引导程序将具有以下html


动物教区的陈词滥调。。。
.......

您的引导javascript文件在页面底部引用。

我也一直在努力解决这个问题,我同意将视图相关的内容放在viewModel中会有异味。我需要做你所说的事情的原因是——这不能像建议的那样使用自定义绑定或小部件来完成

我和一位同事提出的最佳解决方案是从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;
});
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;
});
views/awesome.html.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;
});
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;
});

希望有帮助。

附加视图是一件非常危险的小事情。。。把所有的JS代码都放在那里很诱人。。。但这并不理想。我发现的一个小怪癖是在嵌套视图模型中

母公司 步骤1(儿童1) 步骤2(儿童2)

父交换机(child1 child2)

如果父视图操纵子视图(从子视图1交换到子视图2),viewAttached将无法在子视图上正确启动(此时DOM还不可用),并且由于父视图已附加,因此也不会在父视图上运行viewAttached


因此,突然您发现所有JS模块都停止工作,然后您必须为需要由外部JS修改的元素执行自定义绑定。

HTML的javascript应该由绑定或小部件处理。如果你想要一个击倒手风琴,谷歌它。在某些情况下,弹出窗口可以由viewmodel处理。我仍然需要了解委托事件处理程序是如何工作的,但这似乎是一个遵循现有结构约定的优雅解决方案。谢谢委托事件处理程序允许您在父节点上附加事件,然后父节点可以拾取子节点的事件。e、 g.如果您有一个满是按钮的容器,而不是为每个按钮附加一个“单击”事件处理程序,那么您可以在容器上附加一个事件处理程序,用于侦听来自子按钮的任何“单击”事件。非常方便!