敲除绑定顺序/没有可观察量

时间:2013-07-08 14:53:23

标签: javascript knockout.js

我有一个简单的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。这意味着isValidUrlattr集合绑定之前发生。我的问题有两个:

  1. 如何在attr计算函数运行之前确保{em}设置了isValidUrl值?
  2. 看起来isValidUrl应该取决于attr绑定的完成而不是值。有没有正确的方法来做到这一点?

5 个答案:

答案 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)

我不确定这里有时间问题:

  1. 确定是否显示验证消息会关闭 true 值,而不是 false 。请参阅下面的html或此fiddle

  2. 锚的协议在所有浏览器中的行为似乎都不一样。在firefox协议中总是返回“http”,在IE中它确实返回你输入的内容。对于其他人可能会有所不同。

  3. 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