【问题标题】:array reference javascript angular数组参考 javascript 角度
【发布时间】:2014-11-18 14:33:58
【问题描述】:

我正在尝试引用数组中的一项,但我不知道为什么这不起作用,

console.log($scope.Times);
console.log($scope.Times[0]);

这两行代码彼此完全一致,但我从控制台得到的输出如下..

Output from the console

任何想法为什么这不起作用?正如我之前提到的,这些命令彼此完全一致,并且在同一个函数中,变量在我的控制器中是全局的。

如果您认为有帮助,我可以添加更多代码,但我真的不明白如何..

更多代码:

$scope.Times = [];
$scope.getStatus = function(timer){
   $http.post('getStatus.php', {timer : timer})
        .success(function(response){
            $scope.response = response;

            if ($scope.response.Running === "0"){
                $scope.model = { ItemNumber : $scope.response.Part };
                $scope.loadTiming($scope.response.Part);
                console.log($scope.Times);
                console.log($scope.Times[0]);
            }
    });
};

 $scope.loadTiming = function(itemNumber) {
     $http.post('getPartTimings.php', {itemNumber : itemNumber})
        .success(function(response){
            $scope.selectedTiming = response;
            $scope.Times.splice(0); 
            var i = 0;
            angular.forEach($scope.selectedTiming, function(value) {
                if (value !== 0)
                    $scope.Times.push({
                                    "Process" : $scope.procedures[i],
                                    "Duration" : value*60
                                    });   
                i++;
            });
    });
};


<?php


$postData = file_get_contents("php://input");
$request = json_decode($postData);

require "conf/config.php";

 mysqli_report(MYSQLI_REPORT_STRICT);
    try {  
        $con=mysqli_connect(DBSERVER,DBUSER,DBPASS,DBNAME);
    } catch (Exception $exp) {
        echo "<label style='font-weight:bold; color:red'>MySQL Server Connection Failed.     </label>";
        exit;
    }

 $query = 'SELECT *,
            TIME_TO_SEC(TIMEDIFF(NOW(),Timestamp)) 
       FROM live_Timers 
       WHERE Timer='.$request->timer;

 $result = mysqli_query($con, $query);
 $data = mysqli_fetch_assoc($result);

 echo JSON_ENCODE($data);

感谢您的帮助。

【问题讨论】:

  • 更多代码可能会有所帮助,因为根据您现在的情况,我认为没有问题。
  • 更多代码将有助于识别整个上下文以及可能影响数组的其他内容。
  • 它可以在 Firefox 中使用吗?可能与this bug有关。

标签: javascript arrays angularjs


【解决方案1】:

好的,所以更多的代码确实有帮助。看起来您在这里发生了异步逻辑。 loadTiming 被触发,它执行POST,然后在 Times 数组上进行拼接。一个console.log 可能在POST 之前触发,另一个在之后触发。没有简单的方法来判断。

一种可能的解决方法是仅在 loadTiming async 进程运行后记录这些内容。从loadTiming 函数返回一个promise,然后在promise 的then 回调中,记录你的数组。

$scope.getStatus = function(timer){
   $http.post('getStatus.php', {timer : timer})
        .success(function(response){
            $scope.response = response;

            if ($scope.response.Running === "0"){
                $scope.model = { ItemNumber : $scope.response.Part };
                $scope.loadTiming($scope.response.Part).then(function () {

                    console.log($scope.Times);
                    console.log($scope.Times[0]);
                });
            }
    });
};

 $scope.loadTiming = function(itemNumber) {
     return $http.post('getPartTimings.php', {itemNumber : itemNumber})
        .success(function(response){
            $scope.selectedTiming = response;
            $scope.Times.splice(0); 
            var i = 0;
            angular.forEach($scope.selectedTiming, function(value) {
                if (value !== 0)
                    $scope.Times.push({
                                    "Process" : $scope.procedures[i],
                                    "Duration" : value*60
                                    });   
                i++;
            });
    });
};

【讨论】:

  • 哇,看准了!谢谢,还有很多要学习的角度! :)
【解决方案2】:

我认为您的问题是 $scope 参考问题。

我会试试这个:

$scope.vm = {};
$scope.vm.Times = [];

添加“。”附加到 $scope 时是 Angular 的最佳实践。最好在这里描述Understanding Scopes

【讨论】:

    【解决方案3】:

    I have experienced a similar situation a while ago,与this issue相关。

    从那时起,我多次遇到相关问题(AngularJS,由于其循环性质似乎容易产生这种行为)。

    在您的情况下,使用 JSON.stringify($scope.Times) 可能会“解决”这个问题。


    上下文

    这通常发生在这种情况下:

    • 进行了异步调用或昂贵的 DOM 操作。
    • 您在两者之间对 console.log 进行了 2 次(或更多)调用。
    • DOM 或对象的状态发生了变化
    • 输出显示不一致(且奇怪)的结果

    如何

    举个例子:

    console.log(someObject);
    console.log(someObject.property);
    

    经过大量挖掘(并与 Webkit 开发人员交谈),这是我发现的:

    对 console.log 的第二次调用首先“解决”

    为什么?

    在您的情况下,这与控制台如何以不同的方式处理对象和“表达式”有关:

    在调用时解析“表达式”,而对于对象,则存储对所述对象的引用

    请注意,这里使用的表达式很松散。您可以在 this fiddle

    中观察到这种行为

    更深入的分析

    关于显示差异,上面发布的行为并不是控制台的唯一问题。其实和Console的工作方式有关。

    控制台是一个外部工具

    首先您必须意识到 Console 是一个外部工具,而不是 ECMAScript 规范的一部分。浏览器之间的实现有所不同,不应在生产中使用。它肯定不会对每个用户都一样。

    控制台是一个非标准的外部工具,不在标准轨道上。

    控制台是动态的

    控制台是一个非常动态的工具。使用控制台,您可以进行断言(测试)、时间和分析您的代码、分组日志条目、远程连接到您的服务器和调试服务器端代码。您甚至可以在运行时更改代码本身。所以..

    控制台不仅仅是一个静态日志显示器...它的动态特性是其最大的特点之一

    控制台有轻微延迟

    作为一个外部动态工具,控制台作为一个附加到 javascript 引擎的观察程序工作。 这在调试和其他方面非常有用,可以防止 Console 无意中阻止脚本的执行。 简单粗暴的思考方式是将 console.log 想象成一种非阻塞异步调用。这意味着:

    使用控制台,在 1) 调用、2) 处理和 3) 输出之间会有一点延迟。

    但是,调用 Console 本身并不是“即时”的。事实上,它本身可以延迟脚本执行。如果将其与复杂的 DOM 操作和事件混合使用,可能会导致奇怪的行为。

    I've encountered an issue with Chrome, when using MutationObserver and console.log。发生这种情况是因为 DOM 绘制延迟了 DOM 对象的更新,但是由该 DOM 更改触发的事件仍然被触发。这意味着事件回调在 DOM 对象完全更新之前执行并完成,导致对 DOM 对象的引用无效。

    在观察者中使用 console.log 会导致回调执行的短暂延迟,在大多数情况下,这足以让 DOM 对象首先更新。这证明console.log会延迟代码执行。

    但即使发生无效引用错误,console.log 总是显示有效对象。由于代码本身无法更改对象,这证明console.log的调用和处理之间存在延迟延迟。

    控制台日志顺序与代码路径匹配

    控制台日志条目顺序不受条目更新状态的影响。换句话说,

    日志条目的顺序反映了它们被调用的顺序,而不是它们的“新鲜度”

    所以,如果一个对象被更新,它不会移动到日志的末尾。 (对我来说很有意义)


    违反直觉的行为

    这可能导致许多可能的违反直觉的行为,因为人们可能认为 console.log 是对象的某种快照,而不是对它的引用。

    例如,在您的情况下,对象在调用 console.log 和脚本结束之间发生了变化。

    • 调用时$scope.Times为空,所以$scope.Times[0]未定义。
    • 但是,$scope.Time 对象会在后面更新。
    • 显示控制台报告时,会显示对象的更新版本。

    修复

    在您的情况下,将对象转换为“表达式”可以解决“问题”。例如,您可以使用JSON.stringify($scope.Times)


    辩论

    控制台处理对象的方式是 Bug 还是 Feature 值得商榷。有人建议,当使用一个对象调用时,console.log 应该克隆该对象以制作一种快照。有人认为存储对对象的引用更为可取,因为如果您愿意,您可以轻松地自己创建快照。

    【讨论】:

    • +1 让我大吃一惊,我不知道控制台的行为是这样的,我怀疑因为我以前注意到一些奇怪的行为,但这解决了它!谢谢!
    • @SeanBugeja 没有问题的伙伴。它也发生在我身上,令人不安。
    猜你喜欢
    • 2019-01-29
    • 2018-12-31
    • 1970-01-01
    • 2019-01-20
    • 2017-12-29
    • 1970-01-01
    • 2016-11-17
    • 2016-02-27
    • 1970-01-01
    相关资源
    最近更新 更多