考虑以下代码:
if (countriesLookup()) {
countriesLookup().fill(initialData.Countries);
} else {
const subscription = countriesLookup.subscribe(function (lookup) {
lookup.fill(initialData.Countries);
subscription.dispose();
});
}
在这里,我有一个ko.observable
countriesLookup
。如果在数据初始化时组件本身尚未初始化(countriesLookup() == undefined
),则我订阅该可观察的对象,并在它最终获得该组件时,对初始数据执行初始化并取消订阅。暂时让我们忘记这种方法会导致回调地狱等问题,并考虑使这种丑陋变得不那么可能的方法。
我想写一些类似于C#的observable扩展,就像使用中那样:
countriesLookup.initialize(x => x.fill(initialData.Countries));
该实现看起来像这样:
ko.observable.prototype.initialize = function(initializeFunc) {
const currentValue = ???
if (currentValue()) {
initializeFunc(currentValue());
} else {
const subscription = currentValue.subscribe(function (lookup) {
initializeFunc(lookup);
subscription.dispose();
});
}
}
显然,这是行不通的,特别是因为我不确定这是否有可能在“扩展”方法中获取observable的当前值。
我目前在考虑C#编程方面的知识,我对此有些精通,并且希望就如何编写此类扩展名提出一些建议。
也许我应该多解释一下我的问题。我知道可以使用添加到原型的方法中的
this
检索当前值,但是问题在于observable返回一个函数。例如这个
String.prototype.SayHi = function SayHi() {
return "Hi " + this + "!";
};
"blah".SayHi(); //return "Hi blah!"
正常工作,但这
ko.observable.prototype.SayHi = function SayHi() {
return "Hi " + this + "!";
};
var a = ko.observable("blah")
a.SayHi();
失败并显示以下错误:
VM543:1 Uncaught TypeError: a.SayHi is not a function at <anonymous>:1:3
我希望它能增加一些澄清。
最佳答案
如果我明白您的意思,您的目标是为可观察对象添加一个自定义函数。
在这种情况下,应使用fn
而不是prototype
。
查看此链接:http://knockoutjs.com/documentation/fn.html
我不确定这是否有可能在“扩展”方法中获取可观察的当前值
并且您可以使用此方法获取可观测值的当前值,因此,上面的示例非常接近您想要的。
ko.observable.fn.initialize = function(initializeFunc) {
const currentValue = this;
if (currentValue()) {
initializeFunc(currentValue());
} else {
const subscription = currentValue.subscribe(function(lookup) {
initializeFunc(lookup);
subscription.dispose();
});
}
return this;
}
var ViewModel = function() {
this.data = ko.observable().initialize(x => console.log("Value changed to: " + x));
this.data("100");
};
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
================================
注意:关于为什么使用
fn
而不是prototype
的讨论,有人指出,出于某些性能原因,最好使用extenders。在这里阅读:https://github.com/knockout/knockout/issues/979
关于javascript - 用JavaScript编写类似C#的扩展以实现可观察到的 knockout ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47993260/