我的网站上有以下设置。它在任何标准浏览器和任何普通移动浏览器上都运行得非常好:
型号:
function SearchTerm(data) {
this.Term = ko.observable(data.Term);
this.Stamp = ko.observable(data.Stamp);
}
View 模型:
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 »</a>
</div>
所有这些在我测试的所有内容上都完美运行,但有一个主要异常(exception):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
我已经无计可施了。我已经尝试了所有可能的数据绑定(bind)语法组合(如您所见,我也尝试了单引号,因为我曾在某个时候看到过与此相关的帖子)。我现在唯一的猜测是这可能与我的脚本顺序有关。我目前在引用 jquery 之前引用了 knockout——这可能是问题所在吗?我在其他任何地方都没有认为这是一个问题,但在这一点上,我愿意尝试任何事情。
更新:
我的所有其他 knockout 绑定(bind) viewModels 和绑定(bind)在 Android 上工作正常,但它们都不会在页面加载时发生。因此,这促使我考虑将 ajax 更改为一种方法并尝试延迟它的调用。所以我在我的 View 模型中添加了以下内容:
//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
}
});
在我的页面中,这是初始绑定(bind)的样子 - 它出现在页面底部:
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 和 View 都没有这个问题。我还有另外 2 个绑定(bind),他们都有 foreach,似乎没有遇到这个问题。
2013.05.20 更新 我更新了一些代码以反射(reflect)我所做的一些函数/对象重命名,因为我开始担心我有一个名为 history 的变量和一个名为 history 的函数(愚蠢的,我知道,但我'我很绝望)。
我还想发布一个额外的发现。我决定继续尝试从任何加载或就绪事件中删除用于完全加载历史记录的代码。相反,我能够将此数据加载分离到单击按钮中。下面是按钮点击处理程序的样子:
$(".menuButton").on("click", "", function () {
history.searchTerms([]);
history.loadRecent();
});
有趣的是,当我这样做时,仅限 Android。我仍然在加载时遇到错误,在绑定(bind)中:
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
另一个有趣的花絮 - 如果我要从 View 中完全删除 html,这意味着没有绑定(bind),但仍然保留 SearchTerm 模型和 HistoryViewModel 的代码,我仍然会从 Android 中的 WebView 中收到错误,当按钮被点击:
Uncaught TypeError: Object #<History> has no method 'searchTerms' at {url}:681
抱歉发布了这么多,但我很想知道这有什么问题。
最佳答案
也许 webview 使用 HTML 5 history api 做了一些古怪的事情,并将它重置在你的历史 View 模型之上。您是否尝试过将虚拟机名称更改为 historyVM 之类的?我认为你不应该命名你的 View 模型来匹配浏览器本身使用的东西(比如,不要将你的虚拟机命名为“窗口”或“文档”)
关于android - Knockout - 无法仅在 Android WebView 中解析绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16589355/