在angularjs中,当外部作用域的值发生更改时,指令的范围值不会得到更新。

12 浏览
0 Comments

在angularjs中,当外部作用域的值发生更改时,指令的范围值不会得到更新。

我的html代码如下。

    
       选择要由操作员访问的区域
       

我的应用程序的控制器代码如下。当用户在表单中输入一些细节时,会调用getArea函数(此处未包含)。

this.getArea = function(){
        $scope.areanames = [];
        $http({
            method: "GET",
            url: "http://xx.xx.xx.xx/abc",
            params:{city:$scope.city,circle:$scope.circle}
        }).then(function(success){
            for (i = 0; i < success.data.length; i++)
                $scope.areanames.push(success.data[i].area);
        },function(error){
            console.log('error ' + JSON.stringify(error));
        });
    }

multiselect指令的代码如下。

multiselect.directive('multiselect', ['$filter', '$document', '$log', function ($filter, $document, $log) {
        return {
            restrict: 'AE',
            scope: {
                options: '=',
                displayProp: '@',
                idProp: '@',
                searchLimit: '=?',
                selectionLimit: '=?',
                showSelectAll: '=?',
                showUnselectAll: '=?',
                showSearch: '=?',
                searchFilter: '=?',
                disabled: '=?ngDisabled'
            },
            replace:true,
            require: 'ngModel',
            templateUrl: 'multiselect.html',
            link: function ($scope, $element, $attrs, $ngModelCtrl) {
                $scope.selectionLimit = $scope.selectionLimit || 0;
                $scope.searchLimit = $scope.searchLimit || 25;
                $scope.searchFilter = '';
                if (typeof $scope.options !== 'function') {
                    $scope.resolvedOptions = $scope.options;
                }
                if (typeof $attrs.disabled != 'undefined') {
                    $scope.disabled = true;
                }
                $scope.toggleDropdown = function () {
                    console.log('toggleDown');
                    $scope.open = !$scope.open;
                };
                var closeHandler = function (event) {
                    console.log('closeHandler');
                    if (!$element[0].contains(event.target)) {
                        $scope.$apply(function () {
                            $scope.open = false;
                        });
                    }
                };
                $document.on('click', closeHandler);
                var updateSelectionLists = function () {
                    console.log('updateSelectionList');
                    if (!$ngModelCtrl.$viewValue) {
                        if ($scope.selectedOptions) {
                            $scope.selectedOptions = [];
                        }
                        $scope.unselectedOptions = $scope.resolvedOptions.slice(); // Take a copy
                    } else {
                        $scope.selectedOptions = $scope.resolvedOptions.filter(function (el) {
                            var id = $scope.getId(el);
                            for (var i = 0; i < $ngModelCtrl.$viewValue.length; i++) {
                                var selectedId = $scope.getId($ngModelCtrl.$viewValue[i]);
                                if (id === selectedId) {
                                    return true;
                                }
                            }
                            return false;
                        });
                        $scope.unselectedOptions = $scope.resolvedOptions.filter(function (el) {
                            return $scope.selectedOptions.indexOf(el) < 0;
                        });
                    }
                };
                $ngModelCtrl.$render = function () {
                    console.log('render called');
                    updateSelectionLists();
                };
                $ngModelCtrl.$viewChangeListeners.push(function () {
                    console.log('viewChangeListener');
                    updateSelectionLists();
                });
                $ngModelCtrl.$isEmpty = function (value) {
                    console.log('isEmpty');
                    if (value) {
                        return (value.length === 0);
                    } else {
                        return true;
                    }
                };
                var watcher = $scope.$watch('selectedOptions', function () {
                    $ngModelCtrl.$setViewValue(angular.copy($scope.selectedOptions));
                }, true);
                $scope.$on('$destroy', function () {
                    console.log('destroy');
                    $document.off('click', closeHandler);
                    if (watcher) {
                        watcher(); // Clean watcher
                    }
                });
                $scope.getButtonText = function () {
                    console.log('getButtonText');
                    if ($scope.selectedOptions && $scope.selectedOptions.length === 1) {
                        return $scope.getDisplay($scope.selectedOptions[0]);
                    }
                    if ($scope.selectedOptions && $scope.selectedOptions.length > 1) {
                        var totalSelected;
                        totalSelected = angular.isDefined($scope.selectedOptions) ? $scope.selectedOptions.length : 0;
                        if (totalSelected === 0) {
                            return 'Select';
                        } else {
                            return totalSelected + ' ' + 'selected';
                        }
                    } else {
                        return 'Select';
                    }
                };
                $scope.selectAll = function () {
                    console.log('selectAll');
                    $scope.selectedOptions = $scope.resolvedOptions;
                    $scope.unselectedOptions = [];
                };
                $scope.unselectAll = function () {
                    console.log('unSelectAll');
                    $scope.selectedOptions = [];
                    $scope.unselectedOptions = $scope.resolvedOptions;
                };
                $scope.toggleItem = function (item) {
                    console.log('toggleItem');
                    if (typeof $scope.selectedOptions === 'undefined') {
                        $scope.selectedOptions = [];
                    }
                    var selectedIndex = $scope.selectedOptions.indexOf(item);
                    var currentlySelected = (selectedIndex !== -1);
                    if (currentlySelected) {
                        $scope.unselectedOptions.push($scope.selectedOptions[selectedIndex]);
                        $scope.selectedOptions.splice(selectedIndex, 1);
                    } else if (!currentlySelected && ($scope.selectionLimit === 0 || $scope.selectedOptions.length < $scope.selectionLimit)) {
                        var unselectedIndex = $scope.unselectedOptions.indexOf(item);
                        $scope.unselectedOptions.splice(unselectedIndex, 1);
                        $scope.selectedOptions.push(item);
                    }
                };
                $scope.getId = function (item) {
                    console.log('getID');
                    if (angular.isString(item)) {
                        return item;
                    } else if (angular.isObject(item)) {
                        if ($scope.idProp) {
                            return multiselect.getRecursiveProperty(item, $scope.idProp);
                        } else {
                            $log.error('Multiselect: when using objects as model, a idProp value is mandatory.');
                            return '';
                        }
                    } else {
                        return item;
                    }
                };
                $scope.getDisplay = function (item) {
                    console.log('getDisplay');
                    if (angular.isString(item)) {
                        return item;
                    } else if (angular.isObject(item)) {
                        if ($scope.displayProp) {
                            return multiselect.getRecursiveProperty(item, $scope.displayProp);
                        } else {
                            $log.error('Multiselect: when using objects as model, a displayProp value is mandatory.');
                            return '';
                        }
                    } else {
                        return item;
                    }
                };
                $scope.isSelected = function (item) {
                    console.log('isSelected');
                    if (!$scope.selectedOptions) {
                        return false;
                    }
                    var itemId = $scope.getId(item);
                    for (var i = 0; i < $scope.selectedOptions.length; i++) {
                        var selectedElement = $scope.selectedOptions[i];
                        if ($scope.getId(selectedElement) === itemId) {
                            return true;
                        }
                    }
                    return false;
                };
                $scope.updateOptions = function () {
                    console.log('updateOptions');
                    if (typeof $scope.options === 'function') {
                        $scope.options().then(function (resolvedOptions) {
                            $scope.resolvedOptions = resolvedOptions;
                            updateSelectionLists();
                        });
                    }
                };
                // This search function is optimized to take into account the search limit.
                // Using angular limitTo filter is not efficient for big lists, because it still runs the search for
                // all elements, even if the limit is reached
                $scope.search = function () {
                    console.log('search');
                    var counter = 0;
                    return function (item) {
                        if (counter > $scope.searchLimit) {
                            return false;
                        }
                        var displayName = $scope.getDisplay(item);
                        if (displayName) {
                            var result = displayName.toLowerCase().indexOf($scope.searchFilter.toLowerCase()) > -1;
                            if (result) {
                                counter++;
                            }
                            return result;
                        }
                    }
                };
            }
        };
    }]);

当areanames在异步更新时,其值未显示在multiselect中。尽管我在html代码中使用了"=",但内部作用域的options值变为undefined。

0