我这里有一个场景,我需要使用属性绑定(bind) (attr
) 但是要应用的实际值是通过回调返回的,所以有什么方法可以让 knockout 以某种方式成为回调感知?
我假设答案是否定的,我将需要使用一个异步 knockout 插件,但由于其中一些需要 dirtyflags 等设置,我不想用这些东西使我的模型复杂化。
下面是一个代码示例:
function SomeViewModel()
{
var someStorageMechanism = new StorageMechanism();
this.GetUserPicture = function(userId) {
someStorageMechanism.GetUserData(userId, function(userData) {
// should really be using a callback argument then do callback(userData.picture); but knockout has no notion of this
});
};
}
<img data-bind="attr: { src: GetUserPicture($data.userId) }"/>
在上面的示例中,GetUserPicture
理想情况下应该返回图像数据字符串或 url,但是在这种情况下需要从异步工作的底层对象中检索数据,因此是否有任何简单的解决这个问题的方法?
最佳答案
“有什么方法可以让 knockout 以某种方式成为回调感知?”
是的,您可以使用订阅。所有 observables、observableArrays 和 computeds 都继承自 subscribable 类型,因此您可以这样做:
var foo = ko.observable("foo");
foo.subscribe(function (newValue) {
// When foo updates, this function is called
});
通过订阅,您甚至可以设置临时订阅并在以后不再需要时取消订阅。
var fooSub = foo.subscribe(function (newValue) {
// When foo updates, this function is called
});
// Somewhere else in the app...
fooSub.dispose();
默认情况下,订阅会订阅名为“更改”的主题。这意味着当 observable 的值发生变化时,它会使用 newValue(因此是参数的名称)调用任何订阅者,但您也可以设置订阅主题“beforeChange”的订阅,以便在某个值之前执行逻辑变化。
foo.subscribe(function (oldValue) {
// Do logic on the oldValue here
}, null, 'beforeChange');
您可以在 knockout 的 documentation 中阅读相关内容.但如果需要,您也可以订阅自定义主题。默认情况下,当 observables 的值发生变化时,'beforeChange' 和 'change' 主题会在值变化之前和之后(分别)触发。但您可以订阅一个自定义主题,稍后您可以手动触发该主题,以通知收听该主题的所有订阅者。
foo.subscribe(function (value) {
// Do logic when observable notifies subscribers to the 'customTopic' topic
}, null, 'customTopic');
// Somewhere else in the app...
var value = "bar";
foo(value);
foo.notifySubscribers(value, 'customTopic');
通过这种方式,您可以在彼此没有直接引用的独立 View 模型之间建立通信。这是我对如何做到这一点的粗略理解,您可以通过观看 Ryan Niemeyer 的提示和技巧来了解更多信息 video .特别是订阅部分。
通过这种方式,您可以在 knockout 中执行一种回调。另请查看 Ryan 的 Knockout-postbox将 observables 扩展到 subscribeTo 和 publishOn 这些主题的库。
您还可以查看 jQuery $.Deferreds这是 $.ajax 请求使用的基础部分。这不是 knockout 回调,而是一种回调。
让我知道这是否是您正在寻找的更多内容。
关于javascript - 异步函数作为 knockout 绑定(bind)目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18631459/