Knockout属性绑定中的'readonly'和'disabled'等属性是什么意思?

26

如何使用Knockout的"attr"数据绑定来处理像"readonly""disabled"这样的独立属性,这是推荐的"最佳实践"方法?

这些属性有点特殊,通常将属性值设置为属性名称即可启用它们(尽管许多浏览器在HTML中只包含属性名称而没有任何值时也能正常工作):

<input type="text" readonly="readonly" disabled="disabled" value="foo" />

然而,如果你不想应用这些属性,通常的做法是从HTML中完全省略它们(而不是像使用readonly="false"之类的方法):

<input type="text" value="foo" />

Knockout的“attr”数据绑定不支持这种情况。只要我提供了一个属性名称,就需要同时提供一个值:

<input type="text" data-bind="attr: { 'disabled': getDisabledState() }" />

有没有一种跨浏览器的方法可以关闭“禁用(disabled)”或“只读(readonly)”?或者是否有一个自定义绑定技巧,如果我不想让项目被禁用或只读,我可以使用它来不渲染任何东西?


我不理解,为什么您需要提供“disabled”属性,如果您甚至不禁用也能显示? - jjperezaguinaga
我给出的示例旨在简单地演示问题。问题在于:HTML中的某些属性是独立属性-它们实际上不需要值。如果您不希望这些属性影响HTML,则可以简单地省略它们。但是,Knockout的“attr”数据绑定机制不支持此场景。 - Armchair Bronco
3个回答

41

Knockout的“attr”数据绑定支持此场景,只需从你的getDisabledState()函数返回nullundefined,它就不会生成该属性。

演示Fiddle


我该如何验证属性是否已经被Firebug或类似工具发出?当我尝试查看上面演示Fiddle的“实时”HTML时,我仍然看到Knockout数据绑定代码,而不是实时呈现的<INPUT>标签。 (但是,我承认我从来没有想过这样做;在我的getDisabledState()函数中,我总是返回“disabled”或空字符串“”)。 - Armchair Bronco
如果我的小提琴在您的浏览器上工作,则它正在工作。我不使用Firebug。在Chrome开发工具中,如果您返回“disabled”和“undefined”,则很明显它会添加和删除属性。 - nemesv
好的。我已经使用Chrome验证过了。感谢快速回复和演示的Fiddle。这是一个简单而优雅的解决方案,我从未想到过。我通常将返回值初始化为预期的数据类型(对于“disabled”或“readonly”来说,这是一个字符串)。我只需初始化为“undefined”,就应该可以了。谢谢! - Armchair Bronco
3
如果getDisabledState()函数返回true/false,你可以在不修改函数的情况下使用三目运算符来内联处理:<input type="text" data-bind="attr: { 'disabled': getDisabledState() ? 'disabled' : null }" />这将产生与返回字符串或null相同的效果。 - Jacob Jedryszek

9
您可以像这样创建只读绑定:
ko.bindingHandlers['readonly'] = {
'update': function (element, valueAccessor) {
    var value = ko.utils.unwrapObservable(valueAccessor());
    if (!value && element.readOnly)
        element.readOnly = false;
    else if (value && !element.readOnly)
        element.readOnly = true;
}
};

来源:https://github.com/knockout/knockout/issues/1100

这是一个解决IE浏览器下的内存泄漏问题的补丁。当在Internet Explorer中使用 Knockout.js 库时,可能会导致内存泄漏问题。通过此补丁,可以修复这个问题并解决内存泄漏。

感谢分享源代码,并将代码嵌入行内。 - John Zabroski
很棒的文章!您能否也包含一个如何使用它的演示?我相信我可以弄清楚,但我以前从未制作过自定义绑定,这对其他人也会有用。 - jpaugh
@jpaugh,抱歉,我已经好几年没有使用KO了。现在,我使用Aurelia框架。 - Greg Gum

7

Knockout提供了一个enable绑定以及一个disable绑定。

我不确定在问题提出时是否已经有这些选项,但任何参考这个问题的人都应该知道。


1
一定要选择正确的。!observableProperty 不起作用。评估器无法识别 NOT ! - P.Brian.Mackey
4
!observableProperty() 的工作效率比自定义绑定通常更快,而且经常更加简洁。 - mikus
1
@P.Brian.Mackey 这是一个常见的Knockout初学者错误。当在observableProperty前添加!等运算符时,需要在propertyName末尾显式调用它,通过添加()。这告诉Knockout将整个表达式提升为合成计算。如果使用Chrome Debugger并键入不存在的虚拟属性,它将在控制台中生成带有VM:SomeLineNumber的错误。单击VM:SomeLineNumber,您将看到Knockout生成的内容。 - John Zabroski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接