在Knockout JS中保存对DOM元素引用的正确模式
Correct pattern to hold a reference to a DOM element in Knockout JS
我知道在Knockout模型中处理DOM是一种不好的做法。但是,保存对模型中元素的引用的正确模式是什么呢?
假设我有一个菜单模型:
MenuModel = function()
{
var self = this;
self.buttons = [{ text: "set color" }, { text: "set border" }];
};
现在,这个菜单表示一个DOM元素,菜单中的每个按钮都操作所表示元素的DOM。
这是存储元素引用的正确模式吗?
MenuModel = function(el)
{
var self = this;
self.element = el;
self.buttons = [{ text: "set color" }, { text: "set border" }];
};
因此,当单击菜单按钮时,该按钮的父模型(MenuModel)保存对元素的引用。
我理解解决方案是为所表示的元素提供一个Knockout模型,并更改该模型,以便元素根据模型更改而更改。但这对我来说是不实际的,在这一点上,我真的需要直接改变元素DOM。
为什么要在JS中保存DOM元素的引用?我认为这是一种反模式。看看这张来自维基百科的MVVM图表。显然你的MenuModel
不是一个真正的模型,而是一个viewModel
;它不包含任何数据,只包含表示逻辑。模型将是您从后端获得的JSON/XML数据,并最终通过构造函数转换为命名对象实例。viewModel (JS)和view (HTML)之间的流通过data-binding
绑定。如果您坚持使用Knockout提倡的模式,则应该保持如下的简单:
<ul data-bind="foreach: buttons">
<li data-bind="text: text"></li>
</ul>
您可以简单地向每个按钮对象添加一个action属性,并传递参数yourFunction(data, e)
来操作您的视图,如下面的代码片段所示。如果您需要访问视图层次结构中的其他元素,您可以始终为其添加一个类/id,然后使用ko.dataFor(elem)
或ko.contextFor(elem)
引用其数据。
<ul data-bind="foreach: buttons">
<li data-bind="text: text, click: action"></li>
</ul>
为了性能和代码的可读性,您可能不希望将事件绑定附加到每个元素(特别是在列表中)。在这种情况下,请参考Knockout的低调事件处理部分或其他解决方案,如R.Niemeyer的插件Knockout委托事件。
所以要回答But what would be the correct pattern to hold a reference to an element in a model?
-我会说,没有。在我所编写的所有Knockout代码中,我想不出有哪一种情况需要这样做。如果这还不能让人信服,那就读一读什么是关注点分离?
- 如何通过向用户推送模式引用来更新用户对象's数组字段
- 我应该如何在JS中使用揭示模块模式,传递引用,并避免加载顺序问题
- 当链接中引用视频时,是否可以在iPad上以全屏模式打开.mp4
- 单个模式数组中的多个模式引用 - 猫鼬
- 是否可以在猫鼬中相互引用两个模式
- 在单例模式中引用变量的根父级
- 以严格模式在未知环境中获取对全局对象的引用
- 此模式是否会导致闭包中出现循环引用
- 引用Mongoose中的另一个模式
- Javascript模式:引用"this"在私人和公共场合
- JavaScript内置语言特性或API函数在严格模式下引用undefined属性时返回undefined
- Javascript:使用"模块模式"引用变量,有什么想法吗?
- 在Backbone中保存对全局集合的引用的最佳模式
- 如何在Twitter Bootstrap's弹出模式中引用html表单字段?
- javascript正则表达式模式的反向引用
- Javascript模块模式未捕获的引用错误
- 我似乎不能引用2模式填充之后
- 引用对象实例的React.js模式
- Javascript regexp:在反向引用模式中使用变量
- 使用angular显示被引用模式的信息