我正在使用TypeScript和Knockout编写应用程序,并且在最近几天尝试扩展viewmodel中使用的ko.observable对象,以便能够执行以下操作:
HTML:
<input type="text" data-bind="value: myvalue" />
<button data-bind="click: enable">Enable</button>
<button data-bind="click: disable">Disable</button>
视图模型:
interface KnockoutObservableFunctions<T> {
enabled(enabled: boolean): void;
}
class MyModel {
public theValue: KnockoutObservable<string>;
constructor() {
ko.observable.fn.enabled = function (enabled: boolean) {
// This is not working because I don't have access to the
// elements, but it should illustrate my intentions.
$(elements[0]).prop("disabled", !enabled);
}
this.theValue = ko.observable("A string");
}
public enable(): void {
this.theValue.enabled(true);
}
public disable(): void {
this.theValue.enabled(false);
}
}
也就是说,我想访问绑定到我在fn上附加的自定义函数中的observable的DOM节点,如上面的代码所示。我怎么做?我尝试过自定义绑定,但这似乎不太合适。
我知道Knockout中的启用/禁用绑定,我最终想做的事情可以通过使用其他observable来完成,即将viewValueEnabled observable添加到viewmodel。
答案 0 :(得分:0)
就个人而言,我会选择添加enabled
观察者的扩展器。我还要注意每当你想要一个带有DOM元素的东西时,自定义绑定是唯一的方法 。 :)
然后,您有两个选择:
enable
绑定添加到嵌套的observable:enable
:myValue.enabled`(你说你不想使用这个绑定,但我想你应该和我提到它给它一个完整的答案)value
和enable
绑定的绑定。在下面的示例中,您可以看到两个绑定。我没有真正看到第二种方法的好处,因为它模糊了逻辑,最终可能出现在许多不同的绑定中。 (例如,你需要另一个textInput
绑定。)
(我不知道打字稿,所以这个例子是普通的js。希望没关系。)
ko.extenders.enabled = function(target, initialVal) {
target.enabled = ko.observable(initialVal);
return target;
}
ko.bindingHandlers.enabledValue = {
init: function(el, va) {
ko.applyBindingsToNode(el, {
value: va(),
enable: va().enabled
});
}
}
var VM = function() {
this.myValue = ko.observable("test")
.extend({
enabled: true
});
this.enable = this.myValue.enabled.bind(null, true);
this.disable = this.myValue.enabled.bind(null, false);
}
ko.applyBindings(new VM());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div>
Two bindings:
<input type="text" data-bind="value: myValue,
enable: myValue.enabled" />
</div>
<div>
One binding:
<input type="text" data-bind="enabledValue: myValue" />
</div>
<button data-bind="click: enable">Enable</button>
<button data-bind="click: disable">Disable</button>