我有一个简单的viewmodel:
<input data-bind="value: url">
<a id=url-host data-bind="attr: { href: url }"></a>
<div data-bind="visible: isValidUrl">
This is not a valid URL
</div>
function () {
var self = this;
self.url = ko.observable();
self.isValidUrl = ko.computed(function () {
return !!$("#url-host").get(0).protocol;
});
}
我遇到的问题是,当输入发生变化时,似乎没有触发isValidUrl
。我可以通过在self.url()
函数内的任何位置添加ko.computed
来解决此问题。似乎ko.computed
只有在包含对observable的调用时才会被触发,这实际上是有意义的。
但是,通过在上面的代码中添加self.url()
,$("#url-host")
href
属性实际上仍为undefined
。这意味着isValidUrl
在attr
集合绑定之前发生。我的问题有两个:
attr
计算函数运行之前确保{em}设置了isValidUrl
值?isValidUrl
应该取决于attr
绑定的完成而不是值。有没有正确的方法来做到这一点?答案 0 :(得分:2)
目前尚不清楚您尝试实现的目标。但是你使用knockoutjs来避免这种dom选择,特别是当你分配url时。
我创建了一个fiddle,它大致做了我怀疑你可能想要的事情
self.isValidUrl = ko.computed(function () {
return !!URI(self.url()).protocol();
});
我不得不求助于Uri.js库,因为我找不到从普通javascript中的字符串中获取协议的方法。
答案 1 :(得分:0)
您可以使用“throttle”扩展器来延迟计算的observable的评估:
self.isValidUrl = ko.computed(function () {
self.url();
return !!$("#url-host").get(0).protocol;
}).extend({ throttle: 1 });
但是,请注意,只有在输入字段失去焦点时才会更新可观察的“url”,而不是在您输入时。
答案 2 :(得分:0)
ad 1.只要您调用ko.applyBindings()
,就会遍历DOM,并解析所有绑定。那时url
变量仍为undefined
,因为这是您初始化它的方式。
广告2.此外,正如您所说,computed
变量应取决于observable
。如果您不想这样做(无论出于何种原因),您仍然可以订阅url
观察点,并在回调中参考href
属性。请在此处查看the documentation。
myViewModel.url.subscribe(function(newValue) {
// use $("#url-host") here
// ...
});
答案 3 :(得分:0)
我不确定这里有时间问题:
确定是否显示验证消息会关闭 true 值,而不是 false 。请参阅下面的html或此fiddle。
锚的协议在所有浏览器中的行为似乎都不一样。在firefox协议中总是返回“http”,在IE中它确实返回你输入的内容。对于其他人可能会有所不同。
将 isValidUrl 计算为在此方案中多次触发需要触发器,在此example中我使用了url observable。
self.isValidUrl = ko.computed(function () {
var trigger = self.url(); // trigger re-evaluation
return !!$("#url-host").get(0).protocol;
});
<div data-bind="visible: !isValidUrl()">
This is not a valid URL
</div>
答案 4 :(得分:-1)
您是否尝试使用空值初始化您的observable,以阻止它未定义?
self.url = ko.observable('');
然后在你的计算中引用self.url()(我认为你假设计算机应该依赖于你的情况下的observable是正确的。)
您还可以将valueUpdate绑定添加到输入中:
<input data-bind="value: url, valueUpdate: keyup">
以便按每次按键更新值,而不是在输入模糊时更新。
除此之外,我会说你不需要在isValidUrl运行之前设置attr值。每次更改输入值时都会运行。
我已使用此代码创建了jsFiddle。