Knockout - 无法仅在Android WebView中解析绑定

时间:2013-05-16 13:53:34

标签: android jquery html knockout.js android-webview

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

型号:

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之前,我目前参考了淘汰赛 - 这可能是问题吗?我没有在其他任何地方看到这个问题,但在这一点上,我愿意尝试任何事情。

更新

我的所有其他敲除绑定viewModel和绑定在Android上运行正常,但在页面加载时都不会发生。所以这让我看到将ajax更改为方法并试图延迟它的调用。所以我在viewmodel中添加了以下内容:

//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仍然试图迭代,即使没有任何东西存在。我的假设听起来是否正确?任何人都会看到我在这里不知所措会导致这个问题吗?我的其他viewModel和视图都没有这个问题。我有另外两个我有约束力的人,他们都有foreach,但似乎没有遇到过这个问题。

更新2013.05.20 我更新了一些代码,以反映我做的一些函数/对象重命名,因为我开始担心某些东西与我有一个名为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

很抱歉这么多帖子,但我很想知道这有什么不对。

1 个答案:

答案 0 :(得分:0)

也许webview使用HTML 5历史api做了一些古怪的事情,并将其重置在历史视图模型之上。你有没有尝试将vm名称更改为historyVM或其他什么?我认为你不应该命名你的viewmodels来匹配浏览器本身使用的东西(比如,不要命名你的vm'窗口'或'文档')