从淘汰视图模型中访问html元素

时间:2015-04-14 10:20:30

标签: javascript html mvvm knockout.js typescript

我已经创建了一个包含引导模式对话框的淘汰组件,我正在注册并加载(作为AMD模块),如下所示:

// Register dialogs as components
ko.components.register('create-user-dialog', {
    viewModel: { require: 'Features/Users/Index/CreateController' },
    template: { require: 'text!Features/Users/Index/CreateDialog.html' }
});

模板HTML包含如下标记:

<div class="modal fade" id="create-user-modal" tabindex="-1" role="dialog">
...
</div>

淘汰视图模型扩展了一个基类,看起来像这样(typescript):

export = CreateController

class CreateController extends Controllers.BootstrapModalController {

    constructor() {
        super($('#create-user-modal'));
    }
}

class BootstrapModalController {
    public dialog: JQuery;

    constructor(dialog: JQuery) {
        // Save a reference to the modal element so we can 
        // show/hide the dialog from the controller
        this.dialog = dialog;
    }

    // Show the modal window
    showModal = () => {
        this.dialog.modal({
            show: true,
            backdrop: 'static'
        });
    }

    // Close the modal window
    closeModal = () => {
        this.dialog.modal('hide');
    }
}

最后,我使用页面中的组件如下:

<div data-bind="component: 'create-user-dialog'"></div>

这很有效,但它有点乱,因为CreateController做了一些我认为在构造函数中有点奇怪的东西 - 即使用一个jquery选择器,它将它与模板中的html紧密结合。

在某种程度上,这是不可避免的,但我认为它可能会更好一些。如果可能的话,我希望BootstrapModalController基类能够自动确定与Bootstrap模式相对应的DOM元素......那样showModalcloseModal会起作用,因为模板实际上包含一个bootstrap模式对话框,后代不必在构造函数中显式传入id或jquery对象。

我认为它可能能够使用类似jQuery find方法的东西来搜索组件HTML模板中具有CSS类modal的元素。但是,为了做到这一点,我需要能够获取Knockout绑定组件的视图模型的rootNode(即<div data-bind="component: 'create-user-dialog'"></div>元素)。

有没有办法在javascript视图模型中为该组件计算组件的html rootNode?

2 个答案:

答案 0 :(得分:1)

您可以使用自定义绑定,如http://www.knockmeout.net/2011/07/another-look-at-custom-bindings-for.html文章中所述,以便使用Knockout包装HTML / JS元素,例如jquery按钮绑定:

ko.bindingHandlers.jqButton = {
    init: function(element, valueAccessor) {
        var options = valueAccessor() || {};
        $(element).button(options);
    }
};

用法:

data-bind="jqButton: { ...some options... }"

在自定义绑定中,您可以访问应用绑定的元素。

答案 1 :(得分:1)

好的,所以答案似乎是使用绑定处理程序。我找到了this snippet,它看起来像我想要的那样:

ko.bindingHandlers.element = {
    init: function(element, valueAccessor) {
      var value = valueAccessor();
      value(element);
    }
};

作者演示:

<canvas width="100" height="60" data-bind="element: yourObservable"></canvas>

所有似乎都相当轻松地工作......关于唯一的事情就是在我的情况下我必须从元素中创建一个JQuery对象:

ko.bindingHandlers.element = {
    init: function(element, valueAccessor) {
      var value = valueAccessor();
      value($(element));
    }
};

感谢罗伯特提示!