获取与 Knockout 绑定的 observable 元素?
Posted
技术标签:
【中文标题】获取与 Knockout 绑定的 observable 元素?【英文标题】:Get element an observable is bound to with Knockout? 【发布时间】:2012-03-16 22:28:48 【问题描述】:这不是一个理想的情况,但由于我正在使用另一个淘汰赛绑定,我需要获取一个可观察对象绑定到的元素,如果它确实绑定到任何东西。
那么有没有办法做到这一点?
== 更新 ==
我不想添加任何额外的上下文以防它混淆问题,但因为它可能会得到更符合预期的答案,所以这里是场景。
我正在使用敲除验证绑定,它使用ko.validation.group(model)
方法公开所有错误。然而问题是 only 给你文本错误,它没有给你任何关于模型的哪个部分给你这些错误的上下文。所以我对源代码做了一个小改动,现在将与每个错误相关的 observable 传回,因为这可能对一些场景有用,但是从这里我需要能够将它绑定到一个元素,以便我可以显示一些某种形式的在线验证。
Knockout Validation 提供了一个非常基本的内联验证,它在你的元素之后创建一个跨度,你可以给它一个类,但这对于我的需求来说太基本了,因为目前我们正在使用 Qtip 和其他通知系统来显示验证错误,因此我需要能够有一个 Dom 元素和一个错误。到目前为止,我有一个可观察对象和一个错误,但我需要将该可观察对象(可以是模型中的任何 ko.observable() 属性)绑定到其给定的 DOM 元素,如果它确实具有元素绑定。
由于我只有一个对象,并且我使用的是模型而不是 UI 驱动的验证,因此问题并不能真正通过自定义绑定来解决。理想情况下,我需要能够将可观察对象(未知的ko.observable()
)与元素结合起来。
不要太具体项目,但我当前的项目抽象了事件被触发的验证(即EventSystem.SendEvent(ValidationEvents.ValidationFailed, <element>, <error>)
),然后验证系统监听这些事件并将错误与元素联系起来,无论是工具提示还是咆哮样式通知、警告框等。所以我试图找到在从模型可观察对象而不是 ui 的 DOM 元素(即 jquery-ui)驱动验证时保持这种抽象的最佳方法
== 编辑 2 ==
Knockout Validation 知道可观察对象的元素放入自己的验证元素的方式让我有点吃惊,但是它们只是捎带了现有的值绑定,所以我只是要更改它以添加元素任何基于 isValidatable()
方法的验证元素,至少对于每个错误,我都可以将其绑定到可观察对象,对于具有元素绑定的任何可观察对象,我可以将它们绑定到元素,如果没有,那就没问题它们只是形式广泛的验证错误。我会试一试,因为这应该类似于(尚未测试):
if(utils.isValidatable(valueAccessor()))
valueAccessor().extend(hasElementalBinding: true, elementalBinding: element);
else
valueAccessor().extend(hasElementalBinding: false);
在registerValueBindingHandler
的第 250 行左右,我将把这个问题留待一段时间,以防其他人有更好的解决方案。
【问题讨论】:
相关? ***.com/questions/8911544/… 不是真的,它只是一个自定义绑定,我处于一个可以访问可观察对象的场景,但需要添加一个新的 DOM 元素并知道将其绑定到哪个元素。跨度> 我真的认为您应该编写自己的自定义验证绑定,因为这样您将获得一个元素并可以随心所欲地使用它。 根据您之前的问题重新考虑这种方法后,可能需要编写类似 BoundTo 绑定或将元素注入可观察对象以供以后查找的内容。虽然这听起来很讨厌,但如果元素仅在绑定范围内可用,我真的想不出解决方法......感谢到目前为止的信息。 【参考方案1】:这不会很快,所以我肯定会缓存结果,但是使用 jQuery 的属性选择器:
$('[data-bind*="Property"]')
*=
是属性包含选择器:http://api.jquery.com/attribute-contains-selector/
显然,这不会捕获使用 .subscribe
方法手动订阅的任何内容,但我不确定您将如何从函数中提取元素。
免责声明:虽然这个解决方案可能会奏效,但这对我来说听起来是个可怕的想法,我会改为编写自定义绑定(如 cmets 中所述)或寻找其他解决方案。
【讨论】:
如何获取本例中的属性?这是我的问题的症结所在,我有可观察对象,所以 observable() 给了我它的值,但它可能是 100 个可观察对象中的 1 个,所以我需要理想地知道可观察对象是否有一些唯一可识别的部分我可以使用它来获取 dom 元素,或者即使它以某种方式直接从可观察对象中暴露出来,因为它必须在幕后使用它。我不想用比需要更多的上下文来污染这个问题,但它可能会更好地解释这一点。 啊,那么当前绑定的答案是否定的。但是您可以轻松编写自定义绑定来使用,而不是使用 value 或公开其 dom 元素列表的东西。 您可以在value
绑定的源代码中看到,它实际上并未公开公开 DOM 元素:github.com/SteveSanderson/knockout/blob/master/src/binding/…
我可能错了,但你说的是value
,这是一个绑定,我说的是一个可观察的ko.observable()
,一个是在html中使用的绑定函数,另一个是在 javascript 中使用的变量/函数。我已经编辑了这篇文章,希望能让人们更清楚地了解这个问题。
是的,我明白了,问题是只有绑定绑定到元素,可观察对象只有订阅者,它们是函数。您只能从绑定中获取元素。【参考方案2】:
我做了类似你上面提到的事情。我的数据绑定标签包含一个自定义绑定:
data-bind="... myvalidationbinding: myobservable"
然后在我的绑定处理程序中扩展可观察对象
ko.bindingHandlers.myvalidationbinding =
init: function (element, valueAccessor, allBindingsAccessor, viewModel)
valueAccessor().extend(element: element );
;
最后我的扩展是
ko.extenders.element = function (target, element)
target.DOMElement = element;
现在我可以订阅由 knockout.validation 提供的 isValid(),如果无效,则获取 observable 绑定的元素,然后使用 jQuery 对其进行操作。
【讨论】:
如果 observable 绑定到多个元素怎么办? 扩展 Jon Keto 答案以添加多个绑定在同一个 observable 上的元素:'target.DOMElements = target.DOMElements || []; target.DOMElements.push(element);' +1 多么棒的扩展程序!我不知道从 viewModel 访问 DOM 元素是否是一个好习惯,但就我而言,现在,设计要简单得多。 @vfportero 如果绑定的元素被破坏会发生什么?如何清除参考?以上是关于获取与 Knockout 绑定的 observable 元素?的主要内容,如果未能解决你的问题,请参考以下文章