在angularjs中,当外部作用域的值发生更改时,指令的范围值不会得到更新。
在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。