在淘汰赛中解除视图模型与视图的绑定

Posted

技术标签:

【中文标题】在淘汰赛中解除视图模型与视图的绑定【英文标题】:Unbind view model from view in knockout 【发布时间】:2012-06-17 10:17:46 【问题描述】:

我正在寻找淘汰赛中的解除绑定功能。不幸的是,谷歌搜索和浏览这里提出的问题并没有给我任何关于该主题的有用信息。

我将提供一个示例来说明需要什么样的功能。

假设我有一个包含多个输入的表单。 我也有一个绑定到这个表单的视图模型。 出于某种原因,作为对用户操作的反应,我需要从表单中取消绑定我的视图模型,即由于操作完成,我希望我的所有可观察对象停止对相应值的更改做出反应,反之亦然 - 对可观察对象所做的任何更改都应该' t 影响输入值。

实现这一目标的最佳方法是什么?

【问题讨论】:

【参考方案1】:

您可以使用ko.cleanNode 删除绑定。您可以将其应用于特定的 DOM 元素或更高级别的 DOM 容器(例如,整个表单)。

有关示例,请参阅 http://jsfiddle.net/KRyXR/157/。

【讨论】:

下次写 getElementById 而不是 $("#theid")[0] 最好使用 javascript 而不是 jQuery 来处理所有事情 对于我使用 jquery 的项目,我通常很乐意放弃 1.5ms 以避免输入额外的 15 个字符。如果有机会,我想我会坚持使用 jquery 选择器。 如果超过 1 毫秒我会感到惊讶。 “NetworkError: 404 Not Found - .../knockout-latest.debug.js”。修复演示:jsfiddle.net/KRyXR/156 请注意,cleanNode() 确实(至少从 2.2.1 开始)擦除其事件处理程序的该节点等。当我有一个 ko-bound 引导模式时,对我来说是个坏消息,例如。更多信息:github.com/knockout/knockout/issues/1130【参考方案2】:

@Mark Robinson 的答案是正确的。

尽管如此,我使用 Mark answer 做了以下操作,您可能会觉得这很有用。

  // get the DOM element
  var element = $('div.searchRestults')[0];
  //call clean node, kind of unbind
  ko.cleanNode(element);
  //apply the binding again
  ko.applyBindings(searchResultViewModel, element);

【讨论】:

我必须在手动禁用/启用表单元素后使用它,以恢复淘汰赛enable 绑定的自动性。【参考方案3】:

<html>
    <head>
        <script type="text/javascript" src="jquery-1.11.3.js"></script>
        <script type="text/javascript" src="knockout-2.2.1.js"></script>
        <script type="text/javascript" src="knockout-2.2.1.debug.js"></script>
        <script type="text/javascript" src="clickHandler.js"></script>
    </head>
    <body>
        <div class="modelBody">
            <div class = 'modelData'>
                <span class="nameField" data-bind="text: name"></span>
                <span class="idField" data-bind="text: id"></span>
                <span class="lengthField" data-bind="text: length"></span>
            </div>
            <button type='button' class="modelData1" data-bind="click:showModelData.bind($data, 'model1')">show Model Data1</button>
            <button type='button' class="modelData2" data-bind="click:showModelData.bind($data, 'model2')">show Model Data2</button>
            <button type='button' class="modelData3" data-bind="click:showModelData.bind($data, 'model3')">show Model Data3</button>
        </div>
    </body>
</html>

@Mark Robinson 给出了完美的解决方案,我在单个 dom 元素上遇到了类似的问题,并在这个单个 dom 元素上更新了不同的视图模型。

每个视图模型都有一个点击事件,当点击发生时,每个视图模型的每次点击方法都被调用,这导致在点击事件期间执行不必要的代码块。

在应用我的实际绑定之前,我遵循@Mark Robinson 的方法来清理节点,它确实运行良好。 谢谢罗宾。 我的示例代码是这样的。

function viewModel(name, id, length)
		var self = this;
		self.name = name;
		self.id = id;
		self.length = length;
	
	viewModel.prototype = 
		showModelData: function(data)
		console.log('selected model is ' + data);
		if(data=='model1')
			ko.cleanNode(button1[0]);
			ko.applyBindings(viewModel1, button1[0]);
			console.log(viewModel1);
		
		else if(data=='model2')
		ko.cleanNode(button1[0]);
			ko.applyBindings(viewModel3, button1[0]);
			console.log(viewModel2);
		
		else if(data=='model3')
		ko.cleanNode(button1[0]);
			ko.applyBindings(viewModel3, button1[0]);
			console.log(viewModel3);
		
	 
	
	$(document).ready(function()
		button1 = $(".modelBody");
		viewModel1 = new viewModel('TextField', '111', 32);
		viewModel2 = new viewModel('FloatField', '222', 64);
		viewModel3 = new viewModel('LongIntField', '333', 108);
		ko.applyBindings(viewModel1, button1[0]);
	);
	

【讨论】:

以上是关于在淘汰赛中解除视图模型与视图的绑定的主要内容,如果未能解决你的问题,请参考以下文章

我可以以编程方式触发淘汰视图模型更新吗?

Knockout 将 2 个链接绑定到不同的视图并切换模型视图

添加项目以淘汰视图模型,不更新视图

添加项目以淘汰视图模型,不会更新视图

声明为对象文字与函数的淘汰视图模型之间的区别

两个视图模型之间的淘汰赛传递值