【问题标题】:IE 11 angular scope return function instead of objectIE 11 角度范围返回函数而不是对象
【发布时间】:2016-11-07 06:45:04
【问题描述】:
$scope.updateCart = function() {

    item = $scope.productData;

这段代码 sn-p 在 IE 11 中返回一个函数,而不是像在 chrome 上那样返回对象

导致下面的 $http 请求发送乱码数据。

使用https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js

上一个标题:IE 11 jquery 'Argument not optional' 错误

以下代码:

    dt = $.param({
            shopid: shop_id,
            mtd: method,
            item: item
        });

抛出以下错误:

TypeError: Argument not optional
   at add (https://code.jquery.com/jquery-1.9.1.js:7340:4)
   at buildParams (https://code.jquery.com/jquery-1.9.1.js:7392:3)
   at jQuery.param (https://code.jquery.com/jquery-1.9.1.js:7360:4)
   at $scope.updateBACart (http://127.0.0.1:6636/js/baCartNg.js?v=1478430971:104:3)
   at fn (Function code:2:216)
   at expensiveCheckFn (http://code.angularjs.org/1.5.5/angular.js:15485:11)
   at callback (http://code.angularjs.org/1.5.5/angular.js:25018:17)
   at Scope.prototype.$eval (http://code.angularjs.org/1.5.5/angular.js:17229:9)
   at Scope.prototype.$apply (http://code.angularjs.org/1.5.5/angular.js:17329:13)
   at Anonymous function (http://code.angularjs.org/1.5.5/angular.js:25023:17)

错误在 IE 11 中抛出,但在 chrome 中没有

根据https://docs.angularjs.org/api/ng/service/$httpParamSerializerJQLike

我改代码:

    dt = $httpParamSerializerJQLike({
            shopid: shop_id,
            mtd: method,
            item: item
        });

现在代码没有抛出错误,但是请求是

   item: %0Afunction+item()+%7B%0A++++%5Bnative+code%5D%0A%7D%0A
   mtd: add
   shopid: 1

而不是项目数据。

【问题讨论】:

  • 从最后一个 sn-p 的输出来看,您的 item 变量实际上包含一个 函数。也许您只是忘记调用该函数,例如var item = elements.item 之类的东西应该是var item = elements.item(0)?尝试在该行之前添加 console.log(item) 并查看浏览器控制台中记录的内容。
  • 我注意到,这是我从 NG 范围获得的值 - 这在 IE 11(与 chrome 相比)中是错误的
  • 奇怪的是 IE 和 Chrome 会有所不同。我认为您需要向我们展示更多代码,以便其他人可以更好地了解您的变量发生了什么。
  • 我的猜测是,这实际上与 IE 和 Chrome 本身之间的差异无关,而更像是一种竞争条件,其中 item 是别的东西(承诺,也许)当执行速度变化时。查看更多代码肯定有助于确定确切的问题。
  • 始终提供minimal reproducible example。显示的 sn-ps 只让人们猜测,第一个非常不完整

标签: jquery angularjs internet-explorer-11


【解决方案1】:

当然,您可以将变量命名为 item1 而不是 item,这暂时可以使用...但这并不能告诉您原始代码有什么错误

真正的问题是您分配给全局变量而不是局部变量。使用时:

function () {
    item = (2 + 2); // or some other value
}

没有在它之前使用var item,您实际上是在分配一个全局变量item。在浏览器上下文中,全局作用域是window对象,所以上面等价于:

function () {
    window.item = (2 + 2);
}

在 Chrome 中,没有问题:最初没有window.item,所以这个赋值创建了它。然而,在 IE11 中,window 已经有一个 item 属性,并且它是只读!这意味着对全局 item 变量的所有赋值都会被静默忽略,因此 window.item 始终具有其原始函数值。

您的“解决方案”通过使用不同的变量名来解决这个问题。一个更好、更健壮和更有效的解决方案是使用 locally scoped 变量:

function () {
    var item = (2 + 2); // does NOT create a global item variable
}

作为一种良好做法,请确保在声明新变量时始终使用var,以避免意外创建全局变量。更好的是,在你的函数中添加一个"use strict" 指令,这样这些类型的赋值就会抛出错误,而不是默默地忽略错误。

如果您确实需要创建全局变量,请显式分配给window 对象本身的属性:

function () {
    window.globalItem = (2 + 2);
}

【讨论】:

    【解决方案2】:

    解决方案是item1 = $scope.productData; 而不是item = $scope.productData;

    出于某种原因,IE11 将 item 设置为 function item() { [native code] }

    【讨论】:

    • 我知道发生了什么。由于您使用item = ... 而不是var item = ...,因此您的代码正在尝试分配一个全局 变量item。在 Chrome 上,这不是问题,因为没有 window.item。然而,IE 似乎有一个window.item 函数,并且它是只读。这意味着您对item = ... 的分配实际上失败,并且稍后阅读item 仍然会给您原始window.item。简而言之,真正的问题是您的变量正在泄漏到全局范围 - 使用 var!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 2015-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多