javascript - 可变变量可以从 Angular 服务内的闭包访问

标签 javascript angularjs closures

我正在使用 Angular ui 网格库并尝试填充自定义下拉过滤器。此过滤器只能应用于特定列,这就是为什么我编写了 for 循环来动态访问列。对于每个特定列,我通过我的 Angular 服务向 api 发送请求,以获取过滤器的值,如果响应成功,我会将每个列属性 id 与返回的数据 id 进行比较,然后填充过滤器值。

问题出现在 then 函数内部,IDE 向我显示警告

mutable variable is accessible from closure

并且在 then 函数内部没有任何作用。

我在这里阅读了多个主题,发现我必须执行自调用函数,但它不起作用。

那么我的错误在哪里呢?提前致谢

代码

 for (var i = 0; i <  $scope.columns.length; i++) {

                        // ===== rebuild columns tree =====

                        var execute_ids = [];

                        angular.forEach($scope.columns[i].property, function(){                             
                           if ($scope.columns[i].property.strict === true){

                                if(execute_ids.indexOf($scope.columns[i].property.propertyTypeId) === -1){
                                    execute_ids.push($scope.columns[i].property.propertyTypeId);

                                    lovServices.customPropFilterValue(execute_ids)
                                        .then(function (response) {
                                            (function () {
                                            if (response.id == $scope.columns[i].property.propertyTypeId){

                                                $scope.filter.push({
                                                    value: data.value,
                                                    label: data.value
                                                });

                                                 $scope.columns[i].filter = {
                                                    type: uiGridConstants.filter.SELECT,
                                                    condition: uiGridConstants.filter.EXACT,
                                                    selectOptions: $scope.filter
                                                };
                                            }
                                            })()
                                        });
                                }
                            }
                        });

                    }

原始代码部分

lovServices.customPropFilterValue(execute_ids)
                                        .then(function (response) {
                                            if (response.id == $scope.columns[i].property.propertyTypeId){

                                                $scope.filter.push({
                                                    value: response.value,
                                                    label: response.value
                                                });

                                                $scope.columns[i].filter = {
                                                    type: uiGridConstants.filter.SELECT,
                                                    condition: uiGridConstants.filter.EXACT,
                                                    selectOptions: $scope.filter
                                                };
                                            }
                                        });

编辑

我使用了@JuanTonina提供的解决方案,警告消失了,但又出现了另一个问题。 then 函数中的 i 返回错误值

 (function (i) { /* note that the lovServices call is INSIDE the IIFE*/

            console.log($scope.columns[i].property.propertyTypeId)

 // this console log returns correct ids (120, 123, 194)

            lovServices.customPropFilterValue(execute_ids)
                .then(function (response) {

                    console.log($scope.columns[i].property.propertyTypeId)

 // this console log returns wrong ids (120, undefined, 114)

                    if (response.id == $scope.columns[i].property.propertyTypeId) {

                        $scope.filter.push({
                            value: data.value,
                            label: data.value
                        });

                        $scope.columns[i].filter = {
                            type: uiGridConstants.filter.SELECT,
                            condition: uiGridConstants.filter.EXACT,
                            selectOptions: $scope.filter
                        };
                    }
                });
        })(i)

最佳答案

我将其添加为答案,因为评论不足以表达我的意思。

您的代码应如下所示:

for (var i = 0; i < $scope.columns.length; i++) {

// ===== rebuild columns tree =====

var execute_ids = [];

angular.forEach($scope.columns[i].property, function () {
    if ($scope.columns[i].property.strict === true) {

        if (execute_ids.indexOf($scope.columns[i].property.propertyTypeId) === -1) {
            execute_ids.push($scope.columns[i].property.propertyTypeId);

            (function (i) { /* note that the lovServices call is INSIDE the IIFE*/
                lovServices.customPropFilterValue(execute_ids)
                    .then(function (response) {
                        if (response.id == $scope.columns[i].property.propertyTypeId) {

                            $scope.filter.push({
                                value: data.value,
                                label: data.value
                            });

                            $scope.columns[i].filter = {
                                type: uiGridConstants.filter.SELECT,
                                condition: uiGridConstants.filter.EXACT,
                                selectOptions: $scope.filter
                            };
                        }
                    });
            })(i)
        }
    }
});

}

原因是您的变量 i 在回调中使用之前发生了变化。顺便说一句,如果您使用的是 es6,执行 for( let i = 0;...) 也可以解决问题

关于javascript - 可变变量可以从 Angular 服务内的闭包访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41469719/

相关文章:

javascript - 如何将 node.js 连接到 MySQL

javascript - 使用 angularjs 从表中编辑和保存时出现 CRUD 问题

AngularJS SSL .htaccess 问题

javascript - 我正在尝试使用 join() 函数从 JavaScript 数组中创建一个大字符串,如果可能的话,是否可以包含 html

javascript - 如何使固定标题在滚动时改变颜色

ios - block /闭包理解

javascript - 'var a = 2' 和 'this.a = 2' 之间的区别

Javascript 可链接闭包

javascript - 只有在 Safari 中悬停后,垂直对齐的文本才不会立即正确格式化

javascript - 无类型函数调用可能不接受类型参数 - Angular 5 http 调用