Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/405.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从淘汰视图模型访问html元素_Javascript_Html_Mvvm_Knockout.js_Typescript - Fatal编程技术网

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

Javascript 从淘汰视图模型访问html元素,javascript,html,mvvm,knockout.js,typescript,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/Ind

我已经创建了一个淘汰组件,它包装了一个引导模式对话框,我正在注册和加载(作为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' }
});
<div data-bind="component: 'create-user-dialog'"></div>
模板HTML包含如下标记:

<div class="modal fade" id="create-user-modal" tabindex="-1" role="dialog">
...
</div>
最后,我在页面中使用该组件,如下所示:

// Register dialogs as components
ko.components.register('create-user-dialog', {
    viewModel: { require: 'Features/Users/Index/CreateController' },
    template: { require: 'text!Features/Users/Index/CreateDialog.html' }
});
<div data-bind="component: 'create-user-dialog'"></div>

这是可行的,但它有点混乱,因为<代码> CreateController <代码>在构造函数中做了一些我觉得有点奇怪的事情,即使用jQuery选择器,它将它与模板中的HTML紧密地结合起来。p> 在某种程度上,这是不可避免的,但我认为它可以更好一些。如果可能的话,我希望

BootstrapModalController
基类能够自动确定对应于引导模式的DOM元素。。。这样
showmodel
closeModal
就可以工作,只要模板实际上包含引导模式对话框,并且子体不必在构造函数中显式传递id或jquery对象

我想它可能可以使用类似的方法在组件的HTML模板中查找CSS类为
modal
的元素。然而,为了做到这一点,我需要能够获得将组件的视图模型绑定到Knockout的rootNode(即
元素)


是否有任何方法可以从组件的javascript视图模型中计算出该组件的html根节点

您可以使用自定义绑定,如本文所述,以便使用Knockout包装HTML/JS元素,例如jquery按钮绑定:

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

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

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

好的,所以答案似乎是使用绑定处理程序。我发现,这似乎是我想要的:

ko.bindingHandlers.element = {
    init: function(element, valueAccessor) {
      var value = valueAccessor();
      value(element);
    }
};
作者证明了这一点:

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

谢谢你的提示,罗伯特

处理视图和视图模型之间的绑定是淘汰世界中BindingHandler的责任。我的建议是,您的ViewModel可以有一个名为
isVisible
或类似的属性,您可以为模式创建一个绑定到该属性的bindingHandler。bindingHandler提供了绑定到的(可能可观察到的)值(来自ViewModel)以及应用bindingHandler的元素。只有bindingHandler知道引导DOM操作的API,而不是让ViewModel知道。谢谢Robert。我想我找到了一个和你说的一样的解决办法。因此,基本上,如果您想在viewmodel和dom之间推送内容(在任意方向),绑定处理程序就是答案。。。但这并不是我想要的(我想要的是相反的——将对DOM元素的引用注入视图模型……而不是将视图模型的内容推送到DOM。您还可以通过“$element”上下文属性:data bind=“someBinding:{someParameter:$element}”将当前元素传递给模型。我不确定这是否适用于组件。我更喜欢自定义绑定,因为标记应该取决于模型,而不是其他。将元素传递给模型会破坏MVVM概念(IMO;)。感谢您的确认,但这不是我的建议。:)我同意@TSV的观点,即应该避免将DOM元素推入ViewModel。BindingHandler用于处理DOM和ViewModels之间的绑定。这将使依赖关系保持在视图方向上,并且依赖于ViewModel,而不是同时依赖于视图(DOM)的ViewModel。考虑到将DOM元素推入ViewModel属性的方法,ViewModel会获得对视图(DOM)的依赖性,这使得测试变得更加困难。这是事实,但视图模型中的方法是showModal和closeModal。。。鉴于这些方法的性质,我认为对观点的某种依赖是不可避免的。我想不是所有的用例都可以通过jasmine和单元测试这样的东西轻松地进行测试。。。这可能是需要进行量角器和回归测试的情况之一。@JamesCrosswell您可以很容易地让showModal和closeModal方法设置一个可观察的布尔属性
isShowingModal
。这样,bindingHandler就可以绑定到bool属性,并基于该值显示/隐藏模式。如果你愿意,我可以写一个例子来说明我的意思。请告诉我。