查看模型功能绑定在IE9中未检测到,但在FF和Chrome中有效

时间:2013-11-22 17:46:43

标签: javascript knockout.js revealing-module-pattern

更新 我意识到这个问题很难在实施的情况下遵循。查看和测试工作样本please download the solution.

要测试您必须使用IE9并且无法打开开发工具。打开开发工具将使项目按预期工作。此解决方案适用于任何其他浏览器。为了测试,我在IIS中本地设置了解决方案,并在VS / debug之外运行。


我有一个项目,我试图将一个淘汰赛观察者保存回服务器。我在IE9中看到一些非常奇怪的东西,我无法解释,我希望有人可以帮助我。 我正在使用Asp.NET Mvc以及淘汰赛,并为该项目的这一部分实现了JS揭示模块模式。 我的js文件如下:

  • Reportwriter.js基本绑定到html以显示模式
  • ReportWriterEffects.js这包含UI生成的任何传递给淘汰赛Viewmodel的事件
  • ReportWriterUtilities.js。这包含Viewmodel中的数据/对象操作功能
  • ReportWriterViewModel.js Reportwriter viewmodel Json序列化/序列化。

我的html页面包含以下元素

<a id="footerSaveButton" class="blackGradient panelBtn pleft" >

点击此内容时,会在ReportWriterEffects.js

内调用非突兀事件
 $(document).on({

            click: function () {
                alert('click');// placed here for testing
                var context = ko.contextFor(this);
                context.$root.Save();
            }
        }, '#footerSaveButton');

这应该从ReportWriterViewModel.js调用,看起来像

self.Save = function () {
            if (self.ValidateReport()) {

                // Transform the custom types in the myFilters collection into the form required by the server-side representation.
                self.TransformFilters();
                ReportWriterUtilities.Save(self.iqReport);
            }

将我的报告observable传递给进行ajax调用的reportWriterUtilities.js文件

function Save(reportObservable) {
  // Determine which method to call based upon the state of report modification.
  var command = reportObservable().IsNewReport() ? "SaveNewReport" : "UpdateExistingReport";
$.ajax({
    type: "POST",
    url: "../" + command,
    data: "{ json:'" +
    ko.toJSON(reportObservable, function (key, value) { // Remove the __type attribute. This causes problems with deserialization.
        if (key == "__type") {
            return;
        }
        else {
            return value;
        }
    }) + "'}",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    cache: false,
    success: function (msg) {
        if (msg.Key != null) {
            // Update the ViewModel with properties from the saved Report.
            reportObservable().ReportId(msg.Key.ReportId);
            reportObservable().DateLastModified(msg.Key.DateLastModified);

            AlertMessaging.DisplaySuccess("Report Saved!", 'Your Report has been saved and is available in your Report Library. <i><a target="_self" href="../../ReportLibrary">Go to Report Library</a></i>');
        }
        else {
            // Display an error with the given text.
            AlertMessaging.DisplayError("Problem Saving Report", msg.Value);
        }
    }, error: function (err) {
        AlertMessaging.DisplayError("Error Saving Report", "The Server returned an error code. Code: " + err.status);
    }
    });
}

在Firefox和Chrome中,这一切都有效并且报告已保存。但是在IE中,永远不会调用保存调用。我最初在<a>元素上设置了一个从未调用过的敲除绑定集。我认为浏览器缓存可能对此产生了影响,因为我使用的是Mvc所以我通过将以下属性添加到控制器构造函数来装饰控制器以不加载缓存

[System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public class ReportLibraryController : RootController
{ ...

仍然没有骰子。

如果您查看ajax调用,您还会看到我添加cache: false的地方可能有所帮助。依然没有。

我添加了警告消息,并且确实调用了上下文。$ root.Save();永远不会被称为。

现在这是非常奇怪的事情。当我在IE9中加载页面并按F12在IE中打开开发工具然后关闭开发工具时,调用viewmodel中的save函数并且一切正常。如果我启动浏览器打开开发工具并导航到页面一切正常。控制台中不会生成错误或消息,并且在其他浏览器中一切正常。这似乎与IE9隔离,因为IE 10工作正常。

有没有人有任何建议,或者您过去经历过这样的事情。我很欣赏任何可能导致这种情况发生的原因。我希望下面的代码就足够了。我不能使用小提琴,因为我在这里使用了显示模式而且它没有准确表示代码。

1 个答案:

答案 0 :(得分:4)

在IE8&amp; 9中,每当F12开发人员工具尚未针对当前文档进行初始化时,console都是未定义的(afaik,旧版本的firebug也受此影响)。

ReportWriterViewModel.js(13)中的self.Save console.log('VM reached');似乎失败了。也可能有其他地方,但这是我的 artisan 静态代码分析得到我(无法访问VisualStudio IDE ...或信任未经验证的解决方案:)

只要console调用从生产代码中删除,您就可以继续开发与开放式开发工具一样的常规业务 - 这将是我个人的偏好。

或者,您可以选择使用noop(一种不执行任何操作的方法)“插入”控制台方法:

/*https://stackoverflow.com/a/9593812/1081234*/
if (!window.console) window.console = {};
if (!window.console.log) window.console.log = function () { };

This answer也值得关注,因为它会插入其他控制台方法。