3

我的网站上有以下设置。它在任何标准浏览器和任何普通移动浏览器上都运行良好:

模型:

function SearchTerm(data) {
    this.Term = ko.observable(data.Term);
    this.Stamp = ko.observable(data.Stamp);
}

视图模型:

function HistoryViewModel() {
    //Data
    var self = this;
    self.searchTerms= ko.observableArray([]);

    // Load history from server
    $.ajax({
        type: "GET",
        url: "/api/history/",
        data: null, 
        success: function (msg) {
            var terms = $.map(msg, function (item) { return new SearchTerm(item) });
            self.searchTerms(terms);
        },
        error: function (xhr, ajaxOptions, thrownError) {
            // Error Handling
        }
    });
}

看法:

<div class="title">
            Search History
            <div class="closeBtn"></div>
        </div>
        <div id="historySection">
            <ul class="searches" data-bind="foreach: searchTerms">
                <li class="historyItem">
                    <div class="timestamp"><span data-bind="'text': Stamp"></span></div>
                    <span data-bind="'text': Term"></span>
                </li>
            </ul>
            <a class="loadMore">Load 10 More Searches &raquo;</a>
        </div>

所有这些在我测试的所有东西上都能完美运行,除了一个主要的例外:Android 的 WebView 控件。每当我在那里运行此页面时,都会收到以下异常:

Uncaught Error: Unable to parse bindings.
Message: ReferenceError: Stamp is not defined;
Bindings value: 'text': Stamp at {url}/Scripts/libs/knockout-2.2.1.js:5

我无计可施。我已经尝试过所有可能的数据绑定语法组合(如您所见,我也尝试过单引号,因为我曾在某个时候看到过与此相关的帖子)。我现在唯一的猜测是这可能与我的脚本顺序有关。在我引用 jquery 之前,我目前确实引用了淘汰赛 - 这可能是问题吗?我在其他任何地方都没有将此视为问题,但在这一点上,我愿意尝试任何事情。

更新

我所有的其他淘汰绑定视图模型和绑定在 Android 上都可以正常工作,但它们都不会在页面加载时发生。所以这导致我考虑将 ajax 更改为方法并尝试延迟它的调用。所以我在我的视图模型中添加了以下内容:

//Operations
self.loadRecent = function () {
        // Load search history
        $.ajax({
            type: "GET",
            url: "/api/history/",
            data: null,
            success: function (msg) {
                var terms = $.map(msg, function (item) { return new History(item) });
                self.history(terms);
            },
            error: function (xhr, ajaxOptions, thrownError) {
                //Error handling
            }
        });

在我的页面中,初始绑定如下所示 - 它出现在页面底部:

var history = new HistoryViewModel();

ko.applyBindings(history, $("#historySection")[0]);
//Call page event handlers
$(window).load(function () {
    // Load in our search history
    history.loadRecent();
});

不幸的是,和以前一样的错误。然而,这就是事情变得非常有趣的地方。即使我注释掉对 loadRecent 操作的调用,我仍然会收到错误消息!对我来说,这意味着,出于某种原因,仅对于这个模型,foreach 仍在尝试迭代,即使什么都不存在。我的假设听起来正确吗?有人看到我在这里明显遗漏的任何会导致此问题的东西吗?我的其他视图模型和视图都没有这个问题。我还有另外 2 个绑定,他们都有 foreach 并且似乎没有遇到这个问题。

更新 2013.05.20 我在整个过程中更新了一些代码以反映我所做的一些函数/对象重命名,因为我开始担心我有一个名为 history 的变量和一个名为 history 的函数(愚蠢,我知道,但我很绝望)。

我还想发布一个额外的发现。我决定继续尝试从任何加载或就绪事件中删除用于完全加载历史记录的代码。相反,我能够将此数据加载分离为单击按钮。这是按钮单击处理程序的样子:

 $(".menuButton").on("click", "", function () {
        history.searchTerms([]);
        history.loadRecent();
    });

有趣的事实当我这样做时,仅在 Android 中。在绑定中,我仍然收到加载错误:

 Uncaught Error: Unable to parse bindings.
 Message: ReferenceError: searchTerms is not defined;
 Bindings value: foreach: searchTerms at {url}/Scripts/libs/knockout-2.2.1.js:5

另一个有趣的花絮 - 如果我要从视图中完全删除 html,这意味着没有绑定,但仍然保留 SearchTerm 模型和 HistoryViewModel 的代码,我仍然会从 Android 中的 WebView 收到错误,当按钮是点击:

 Uncaught TypeError: Object #<History> has no method 'searchTerms' at {url}:681

抱歉发了这么多帖子,但我很想弄清楚这有什么问题。

4

1 回答 1

0

也许 webview 使用 HTML 5 历史 API 做了一些古怪的事情,并将其重置在您的历史视图模型之上。您是否尝试过将 vm 名称更改为 historyVM 之类的?我认为您不应该命名您的视图模型以匹配浏览器本身使用的内容(例如,不要将您的虚拟机命名为“窗口”或“文档”)

于 2013-05-27T00:34:15.520 回答