简体   繁体   English

可从角度服务内部的闭包访问可变变量

[英]Mutable variable is accessible from closure inside angular services

I'm working with angular ui grid library and trying to populate custom dropdown filter. 我正在使用angular ui网格库,并尝试填充自定义下拉过滤器。 This filter can be applied only for specific columns that's why I have wrote for loop that to get an access to columns dynamically. 该过滤器只能应用于特定的列,这就是为什么我编写了for循环以动态访问列的原因。 For each specific column I send a request to api thru my angular services that to get values for my filter, and if response successful I compare each columns property id with returned data id, and then populate filter value. 对于每个特定的列,我通过我的角度服务向api发送一个请求,以获取过滤器的值,如果响应成功,则将每个列的属性ID与返回的数据ID进行比较,然后填充过滤器值。

The problem appears inside of then function, the IDE shows me the warning 内部出现的问题then功能,IDE显示我的警告

mutable variable is accessible from closure 可从闭包访问可变变量

and inside of then function nothing works. 和内部then起作用没有什么作品。

I have read multiple topics here and found out that I have to execute self-invoke function, but it doesn't work as well. 我在这里阅读了多个主题,发现我必须执行自调用功能,但是它不能正常运行。

So where is my mistake? 那我的错误在哪里? thanks in advance 提前致谢

code

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

                    }

the original part of code 代码的原始部分

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
                                                };
                                            }
                                        });

EDIT 编辑

I used solution provided by @JuanTonina and the warning is gone, but it appeared another one problem. 我使用了@JuanTonina提供的解决方案,但警告已消失,但似乎又出现了一个问题。 The i inside of then function returns wrong value 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)

I'm adding this as an answer since the comments are not enough to show what I mean. 我将其添加为答案,因为评论不足以显示我的意思。

Your code should look like this: 您的代码应如下所示:

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)
        }
    }
});

}

The reason for this is that your variable i is changing before being used on the callback. 这样做的原因是,您的变量i在用于回调之前正在更改。 As a side note, if you are using es6, doing for ( let i = 0;...) also solves the problem 附带说明一下,如果您使用的是es6,那么for ( let i = 0;...)也可以解决此问题

The problem could be related because you have a Immediately-Invoked Function Expression, or IIFE for short. 由于您有立即调用的函数表达式(简称IIFE),因此可能导致此问题。 And It is executed immediately after it's created. 并且它在创建后立即执行。

Removing from inside your .then() method and it should works fine. 从您的.then()方法内部删除,它应该可以正常工作。

(function () {

})();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM