可以通过角度服务中的闭包访问可变变量

时间:2017-01-04 17:20:01

标签: javascript angularjs closures

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

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

  

可从闭包

访问可变变量

并且在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提供的解决方案并且警告消失了,但它出现了另一个问题。 i函数内的then返回错误的值

 (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)

2 个答案:

答案 0 :(得分:1)

我添加这个作为答案,因为评论不足以表明我的意思。

您的代码应如下所示:

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,那么( let i = 0;...)也可以解决问题

答案 1 :(得分:0)

问题可能是相关的,因为您有一个立即调用的函数表达式,或简称IIFE。它在创建后立即执行。

.then()方法中移除它应该可以正常工作。

(function () {

})();