Jar*_*rem 6 asp.net iis signalr knockout-mapping-plugin knockout.js
所以我有一个简单的Signalr/Knockout项目,它使用映射插件将一个简单的对象(带有更多项的数组的项)绑定到我在JS中定义的viewModel:
var someObjectMapping = {
'MyItemArray': {
create: function (options) {
return new MyItemViewModel(options.data);
}
}
}
var myItemMapping = {
'ItemChildren': {
create: function (options) {
return new ItemChildViewModel(options.data);
}
}
}
var SomeObjectViewModel = function (data) {
ko.mapping.fromJS(data, someObjectMapping, this);
}
var MyItemViewModel = function (data) {
ko.mapping.fromJS(data, myItemMapping, this);
}
var ItemChildViewModel = function (data) {
ko.mapping.fromJS(data, null, this);
}
Run Code Online (Sandbox Code Playgroud)
我使用SignalR的默认设置连接到我的集线器,如下所示:
var myHubProxy = $.connection.myHub;
myHubProxy.client.processSomeObject = function(someObject) {
console.log('SomeObject received');
var viewModel = new SomeObjectViewModel(someObject);
ko.applyBindings(viewModel);
}
$.connection.hub.start().done(function() {
console.log('Now connected, connection ID=' + $.connection.hub.id);
myHubProxy.server.getSomeObject();
});
Run Code Online (Sandbox Code Playgroud)
当我的对象返回时,knockout应用绑定并处理映射.然后,对象及其子数组自然地在页面上呈现:
<h2 data-bind="text: MyItem"></h2>
<ul data-bind="foreach: MyItemArray">
<li>
<span data-bind="text: Name"></span>
<ul data-bind="foreach: ItemChildren">
<li data-bind="text: Name"></li>
</ul>
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
现在对于踢球者:这适用于我的本地机器(Win 10,IIS Express),在所有浏览器(Chrome/Firefox/Safari/IE)中,没问题.但是,当我将其发布到IIS 7.5时,它适用于除Internet Explorer 8-10和Microsoft Edge之外的所有浏览器.相同的代码.
当我浏览F12时,我注意到,从IIS中,第一个映射中的create函数获得了一个数组:
相反,在第一次休息时,我应该在我的数组中拥有第一个项目,就像在我的本地机器上一样:
钻取callstack会发现knockout.mapping的createCallback函数中的父对象没有被解释为数组,因为它应该:
但是,在我的本地计算机上,它按预期工作:
奇怪的是,两件事之一可以解决这个问题:首先,如果我序列化对象,我从SignalR返回,然后在将其绑定到我的淘汰模型之前对其进行解除封装,一切都适用于IIS 7.5中的所有浏览器:
myHubProxy.client.processSomeObject = function(someObject) {
console.log('SomeObject received');
var jsonStr = JSON.stringify(someObject);
var viewModel = new SomeObjectViewModel(JSON.parse(jsonStr));
ko.applyBindings(viewModel);
}
Run Code Online (Sandbox Code Playgroud)
但这会影响性能.
或者,如果我强制SignalR的传输到longPolling,那么所有浏览器中的所有浏览器都适用于IIS 7.5:
$.connection.hub.start({ transport: "longPolling" }).done(function () {
console.log('Now connected, connection ID=' + $.connection.hub.id);
myHubProxy.server.getSomeObject();
});
Run Code Online (Sandbox Code Playgroud)
但是,我不会拥有WebSockets提供的优于轮询的优势.
IIS 7.5不支持WebSockets
我也可以硬编码我的json并将其与knockout绑定,这在所有浏览器中都能正常工作.
我花了很长时间才发现发生了什么,我一直在努力想出这个问题.奇怪的是,当它运行相同的简单脚本时,它在所有其他浏览器中的IIS 7.5中运行,但IE/Edge.它也适用于所有浏览器IIS 10(非Express),这不是我要发布的服务器的选项.
编辑: Uffe指出IIS 7.5不支持WebSockets.在启用日志记录之后,我看到,对于IIS 7.5,Signalr将转而回归到IE的foreverFrame和其他浏览器的serverSentEvents(在IE中不支持).
我还测试了强制foreverFrame,它使用IIS 10 Express在我的机器上重现了这个问题:
$.connection.hub.start({ transport: 'foreverFrame'}).done(function () {
console.log('Now connected, connection ID=' + $.connection.hub.id);
myHubProxy.server.getSomeObject();
});
Run Code Online (Sandbox Code Playgroud)
因此,另一种解决方法是在发布到IIS 7.5时完全从传输中跳过foreverFrame,如下所示:
$.connection.hub.start({ transport: ['serverSentEvents','longPolling']}).done(function () {
console.log('Now connected, connection ID=' + $.connection.hub.id);
myHubProxy.server.getSomeObject();
});
Run Code Online (Sandbox Code Playgroud)
这是一个重现问题的示例项目:https: //onedrive.live.com/redir?resid = D4E23CA0ED671323!1466815&authkey =!AEAEBajrZx3y8e4 &ithint = folder%2csln
归档时间: |
|
查看次数: |
408 次 |
最近记录: |