AngularJS 指令 Select

AngularJS Directive with Select

我在使用 angular 1.6.5 时遇到问题并尝试了所有方法但没有任何明显的进展...

我制定了一个实现 HTML SELECT 标记的指令,该组件似乎可以正常工作,直到我尝试在 option value 属性中获取整个对象而不是单个值或ID。 我可以将选项标签的文本输出为对象的 属性 或通过 return 一些字符串的函数。

这是包含组件和问题的完整 fiddle。 有 3 个示例:

  1. 第一个似乎工作正常,它打印正确的文本和 return 正确的值

  2. 第二个:不起作用,我想将整个对象设置为模型,而不是 属性

  3. 第三个:不起作用,我想将整个对象设置为模型,而不是 属性,但它可以正确打印父控制器中函数的文本.

如何更改我的组件,使其可以 return 既是 属性(如 ID)又是整个对象(JSON 格式很好)?

angular.module("myApp", ['customDrop']).controller("TestController", ['$scope', function($scope) {
  var ITEM_SELECTED = {
    ID: 3,
    VALUE: "VALUE3"
  };
  $scope.LIST = [{
      ID: 1,
      VALUE: "VALUE1"
    },
    {
      ID: 2,
      VALUE: "VALUE2"
    },
    ITEM_SELECTED,
  ];

  $scope.OBJ = {
    LOTTO1: ITEM_SELECTED,
    LOTTO2: ITEM_SELECTED,
    LOTTO3: ITEM_SELECTED

  };

  $scope.getCompleteValue = function(obj) {
    return obj.ID + " - " + obj.VALUE;
  }
}]);

angular.module('customDrop', []).directive('customDrop', function() {
  return {
    restrict: 'E',
    scope: {
      dropid: '@',
      dropvalue: '&',
      list: '=',
      ngModel: '='
    },
    require: 'ngModel',
    template: '<select class="drop" ng-model="ngModel">' +
      '<option ng-repeat="val in list" value="{{getId(val)}}">{{getValue(val)}}</option>' +
      '</select>',
    controller: ['$scope', '$parse', '$timeout',
      function($scope, $parse, $timeout) {
        $scope.getId = function(obj) {
          return obj[$scope.dropid];
        }

        // Can print text option as proerty of through function in parent scope.
        $scope.getValue = function(obj) {
          return !angular.isFunction($scope.dropvalue(obj)) ?
            $scope.dropvalue(obj) :
            $parse($scope.dropvalue(obj))(obj);
        }
      }
    ]
  }
});
.drop {
  width: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>


<div ng-app="myApp" ng-controller="TestController">
  <strong>Simple Text Property (drop id intended to return the ID): (working)</strong><br>
  <custom-drop dropvalue="VALUE" dropid="ID" list="LIST" ng-model="OBJ.LOTTO1"></custom-drop><br> Selected Value: {{OBJ.LOTTO1}}
  <br><br><br>
  <!-- using property as dropValue -->
  <strong>Simple Text Property (drop id intended to return an object): (not working)</strong><br>
  <custom-drop dropvalue="VALUE" dropid="" list="LIST" ng-model="OBJ.LOTTO2"></custom-drop><br> Selected Value: {{OBJ.LOTTO2}}
  <br><br><br>
  <!-- using function as dropValue -->
  <strong>Function Text Property: (not working)</strong><br>
  <custom-drop dropvalue="getCompleteValue" dropid="" list="LIST" ng-model="OBJ.LOTTO3"></custom-drop><br> Selected Value: {{OBJ.LOTTO3}}
</div>

要将所选的整个对象设置为模型,您必须将 getId() 方法修改为 return 对象,以防 $scope.dropid 未通过绑定传递(因为此方法用于生成option)的值。我还建议使用 ngOptions 生成 option 元素的列表。请参阅下面的代码段:

angular.module("myApp", ['customDrop']).controller("TestController", ['$scope', function ($scope) {
    var ITEM_SELECTED = {
        ID: 3,
        VALUE: "VALUE3"
    };
    $scope.LIST = [{
        ID: 1,
        VALUE: "VALUE1"
    },
        {
            ID: 2,
            VALUE: "VALUE2"
        },
        ITEM_SELECTED,
    ];

    $scope.OBJ = {
        LOTTO1: ITEM_SELECTED.ID,
        LOTTO2: ITEM_SELECTED,
        LOTTO3: ITEM_SELECTED

    };

    $scope.getCompleteValue = function (obj) {
        return obj.ID + " - " + obj.VALUE;
    }
}]);

angular.module('customDrop', []).directive('customDrop', function () {
    return {
        restrict: 'E',
        scope: {
            dropid: '@',
            dropvalue: '&',
            list: '<',
            ngModel: '='
        },
        require: 'ngModel',
        template: '<select class="drop" ng-model="ngModel" ng-options="getModelValue(val) as getOptionText(val) for val in list"></select>',
        controller: ['$scope', '$parse',
            function ($scope, $parse) {
                $scope.getModelValue = function (obj) {
                    return !!$scope.dropid ? obj[$scope.dropid] : obj;
                };

                $scope.getOptionText = function (obj) {
                    return !angular.isFunction($scope.dropvalue(obj)) ?
                        $scope.dropvalue(obj) :
                        $parse($scope.dropvalue(obj))(obj);
                }
            }
        ]
    }
});
.drop {
  width: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>

<div ng-app="myApp" ng-controller="TestController">
  <strong>Simple Text Property (drop id intended to return the ID): </strong><br>
  <custom-drop dropvalue="VALUE" dropid="ID" list="LIST" ng-model="OBJ.LOTTO1"></custom-drop><br> Selected Value: {{OBJ.LOTTO1}}
  <br><br><br>
  <!-- using property as dropValue -->
  <strong>Simple Text Property (drop id intended to return an object): </strong><br>
  <custom-drop dropvalue="VALUE" dropid="" list="LIST" ng-model="OBJ.LOTTO2"></custom-drop><br> Selected Value: {{OBJ.LOTTO2}}
  <br><br><br>
  <!-- using function as dropValue -->
  <strong>Function Text Property: </strong><br>
  <custom-drop dropvalue="getCompleteValue" dropid="" list="LIST" ng-model="OBJ.LOTTO3"></custom-drop><br> Selected Value: {{OBJ.LOTTO3}}
</div>