在所选角度上设置动态选项

时间:2015-05-09 06:10:52

标签: javascript angularjs angularjs-directive

我使用Angular选择,我无法设置动态选项。

<div ng-init="delegate.getCategories()">
   <select chosen="" multiple="multiple" 
           ng-model="tags" ng-change="delegate.getCategories()" 
           ng-options="s.categoryName for s.categoryName in tagsList">
   </select>
</div>

我的控制器类

getCategories: function(){
   constantsService.getCategories($scope.category, this.onGetCategories, this.onFailure);
   alert($scope.category);
},

onGetCategories:function(response){
   $scope.tagsList = response.categories;
   alert(response);
},

onFailure:function(response){
   alert(response);
}

在页面加载时,init从后端获取类别,并设置在tagsList变量中,但在html加载时不存在。

1 个答案:

答案 0 :(得分:0)

我的指令angular-chosen运行良好,请参阅代码:

<强> HTML

<select id="selectWithChosen"
        name="selectWithChosen"
        data-ng-model="theSelectedChosenValue"
        data-ng-options="tp as tp.alias for tp in myList"
        sgc-chosen
        data-width="('100%')">
    <option value="">Select One Element</option>
</select>
加载 myList

的内容的

JavaScript

$http.get("/settings/myList").success(function(data) {
    $scope.myList = data;
});

我可以使用下一个代码访问用户选择的值:

//the value of my select with chosen is here, in JS:
//**remember** the variable "theSelectedChosenValue" is only fill after you select the value on chosen component.
$scope.theSelectedChosenValue;

最后,我的角度选择指令的实现:

"use strict";

// baseado em https://github.com/localytics/angular-chosen
components.directive('sgcChosen', function($timeout) {
    var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

    var CHOSEN_OPTION_WHITELIST, NG_OPTIONS_REGEXP, isEmpty, snakeCase;

    NG_OPTIONS_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/;
    CHOSEN_OPTION_WHITELIST = ['noResultsText', 'allowSingleDeselect', 'disableSearchThreshold', 'disableSearch', 'enableSplitWordSearch', 'inheritSelectClasses', 'maxSelectedOptions',
                               'placeholderTextMultiple', 'placeholderTextSingle', 'searchContains', 'singleBackstrokeDelete', 'displayDisabledOptions', 'displaySelectedOptions', 'width'];
    snakeCase = function(input) {
      return input.replace(/[A-Z]/g, function($1) {
        return "_" + ($1.toLowerCase());
      });
    };
    isEmpty = function(value) {
      var key;

      if (angular.isArray(value)) {
        return value.length === 0;
      } else if (angular.isObject(value)) {
        for (key in value) {
          if (value.hasOwnProperty(key)) {
            return false;
          }
        }
      }
      return true;
    };
    return {
      restrict: 'A',
      require: '?ngModel',
      terminal: true,      
      link: function(scope, element, attr, ngModel) {  
        var chosen, defaultText, disableWithMessage, empty, initOrUpdate, match, options, origRender, removeEmptyMessage, startLoading, stopLoading, valuesExpr, viewWatch;
        attr.noResultsText = attr.noResultsText ? attr.noResultsText : "'Sem resultados para: '";
        element.children('chosen-search').children().attr('maxlength', 100);
        element.addClass('localytics-chosen');
        options = scope.$eval(attr.chosen) || {};

        angular.forEach(attr, function(value, key) {
          if (__indexOf.call(CHOSEN_OPTION_WHITELIST, key) >= 0) {
            return options[snakeCase(key)] = scope.$eval(value);
          }
        });

        startLoading = function() {
          return element.addClass('loading').trigger('chosen:updated');
        };

        stopLoading = function() {
          scope.$evalAsync(function() {
              return element.removeClass('loading').trigger('chosen:updated');
          });
        };

        chosen = null;
        defaultText = null;
        empty = false;

        initOrUpdate = function() {
          if (chosen) {
            scope.$evalAsync(function() {
                return element.trigger('chosen:updated');
            });
          } else {
            chosen = element.chosen(options).data('chosen');
            chosen.search_field[0].setAttribute('maxlength', 100);
            return defaultText = chosen.default_text;
          }
        };

        removeEmptyMessage = function() {
          empty = false;
          return element.attr('data-placeholder', defaultText);
        };

        disableWithMessage = function() {
          empty = true;
          scope.$evalAsync(function() {
              return element.attr('data-placeholder', '').attr('disabled', true).trigger('chosen:updated');
          });
        };

        if (ngModel) {
            origRender = ngModel.$render;
            ngModel.$render = function() {
            origRender();
            return initOrUpdate();
        };

        viewWatch = function() {
          return ngModel.$viewValue;
        };

        scope.$watch(viewWatch, ngModel.$render, true);
        } else {
          initOrUpdate();
        }

        attr.$observe('disabled', function(isDisabled) {
            scope.$evalAsync(function() {
                element.prop('disabled', isDisabled);
                element.trigger('chosen:updated');
            });
            return true;
        });

        if (attr.ngOptions && ngModel) {
          match = attr.ngOptions.match(NG_OPTIONS_REGEXP);
          valuesExpr = match[7];
          return scope.$watchCollection(valuesExpr, function(newVal, oldVal) {
            if (angular.isUndefined(newVal)) {
              return startLoading();
            } else {
              if (empty) {
                removeEmptyMessage();
              }
              stopLoading();
              if (isEmpty(newVal)) {
                return disableWithMessage();
              } else {
                  element.attr('data-placeholder', '').attr('disabled', false).trigger('chosen:updated');
              }
            }
          });
        }
      }
    };
  });

此角度选择的代码可用HERE