【问题标题】:Why doesn't knockoutjs run this computed function when the page is loaded?为什么在页面加载的时候,knockoutjs 不运行这个计算函数?
【发布时间】:2018-02-20 13:35:13
【问题描述】:

我正在使用 Google Maps API 和 KnockoutJS,在创建地图标记后,我将它们传递给它们,连同动画(显示信息窗口和弹跳标记)和位置名称到 observableArray 中,如下所示:

viewModel.addMarkersForKo(marker, venueName, doAnimation);

这(上图)采用标记、标记名称 (venueName) 和动画(显示传递的标记的信息窗口、信息窗口的内容和标记图标动画等之间的一长串组合)

addMarkersForKo: (aMarker, markerName, animation) => {
        let marker = {
            marker: aMarker,
            name: markerName,
            animation: animation
        };
        koViewModel.allMarkers().push(marker);
    }

这是我获取值并将它们进一步推入 observableArray 以进行 Knockout 的地方。

let koViewModel = {
    allMarkers: ko.observableArray()
};

koViewModel.Query = ko.observable('');

koViewModel.Search = ko.computed( () => {
    let q = koViewModel.Query();
    return koViewModel.allMarkers().filter( 
        (i) => i.name.toLowerCase().indexOf(q) >= 0
    )
});

最后,这就是淘汰赛被绑定的所有内容,因为在完成所有这些之前,我将其绑定如下:

ko.applyBindings(koViewModel);

这(下)是我的 html 绑定:

<input data-bind="textInput: Query, valueUpdate: 'keyup'" type="search" placeholder="Filter...">
<ul data-bind="foreach: Search">
    <li data-bind="text: name, click: animation"></li>
</ul>

一切都完美无缺,因此不需要其他代码。它通过标记列表正确过滤并单击列表项弹出正确的标记等等!

问题是加载页面后,列表是空的,只有在我在里面输入一个字母后它才会显示列表项......如果我按'A'然后'Backspace'它会显示列表中的所有标记。 我已经用控制台记录了 ko.computed 的结果对此进行了测试,它只在按下一个键后运行,在我按下一个键之前它会返回未定义。 如何让它在页面加载后立即返回标记并组成列表项。

【问题讨论】:

  • 你确定代码没有被触发吗? foreach: 绑定应该评估 Search observable,因此如果您在 chrome devtools 中的代码上设置断点,您应该会看到它被触发一次。但是,由于 filter() 操作,它的初始评估可能是空的。但是当你输入一个值时会发生一些事情,这意味着计算是由可观察的查询触发的。

标签: javascript google-maps google-maps-api-3 knockout.js


【解决方案1】:

一开始就使用afterRender绑定来执行。

<input data-bind="textInput: Query, valueUpdate: 'keyup'" type="search" placeholder="Filter...">
<ul data-bind="foreach: Search, afterRender: Search">
    <li data-bind="text: name, click: animation"></li>
</ul>

【讨论】:

  • 不幸的是,它不起作用,什么也没有发生,而且它无助于 KnockoutJs 几乎没有错误处理。
【解决方案2】:

代码: koViewModel.allMarkers().push(marker); 正在展开您的 observableArray,然后将数据直接推送到底层数组中(在依赖跟踪器的知识之外)。我建议将其更改为:

koViewModel.allMarkers.push(marker); // note, pushing on the observableArrray, not the unwraped, underlying array

【讨论】:

    猜你喜欢
    • 2021-07-10
    • 2013-11-03
    • 1970-01-01
    • 2012-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    相关资源
    最近更新 更多