import template from "./Select.html"; import style from "antd/lib/select/style/index.css"; angular .module("esNgAntd") .directive("esSelect", function ($compile, $timeout, esNgAntd) { return { controllerAs: "esSelect", restrict: "E", transclude: true, replace: true, scope: { value: "@", defaultValue: "@", placeholder: "@", onChange: "&", placeholder: "@", getPopupContainer: "&", size: "@", }, template: template, controller: function ($scope, $element, $attrs) { this.getContext = function () { return $scope; }; $scope.state = { open: false, childrens: [], label: null, value: $scope.value || $scope.defaultValue, popup: null, }; $scope.setValue = function (value) { let option = $scope.state.childrens.find(function (option) { return option.value === value; }); if (option) { option.label = option.element.text(); $scope.state.label = option.label; $scope.state.value = option.value; } else { $scope.state.label = null; $scope.state.value = null; } }; $scope.addOption = function (option) { $scope.state.childrens.push(option); }; $scope.handleClick = function (option) { $scope.state.open = !$scope.state.open; $scope.state.label = option.label; $scope.state.value = option.value; $scope.onChange({ value: $scope.state.value, }); }; $scope.getOffset = function (ele) { if (!ele || ele.nodeType != 1) { return; } let func = $scope.getPopupContainer(); if (typeof func === "function" && func() !== undefined) { let containerElement = func(); containerElement.style.position = "relative"; return { top: $element[0].offsetTop, left: $element[0].offsetLeft, }; } else { let rect = ele.getBoundingClientRect(); let doc = ele.ownerDocument.documentElement; return { top: rect.top + window.pageYOffset - doc.clientTop, left: rect.left + window.pageXOffset - doc.clientLeft, }; } }; $scope.myEvent = function () { $timeout(() => { $scope.state.open = false; document.body.removeEventListener( "click", $scope.myEvent ); }, 0); }; $scope.handleBlur = function () { // 事件绑定 document.body.addEventListener("click", $scope.myEvent); }; $scope.handleOpen = function (event) { event.stopPropagation(); const { height, width } = $element[0].getBoundingClientRect(); const { top, left } = $scope.getOffset($element[0]); // 处理标签 $scope.state.childrens.forEach(function (item) { item.label = item.element.text(); }); let div = document.createElement("div"); div.style.position = "absolute"; div.style.left = 0; div.style.top = 0; div.style.width = "100%"; div.appendChild( $compile(`
{{option.label}}
`)($scope)[0] ); if ($scope.state.popup === null) { let func = $scope.getPopupContainer(); if ( typeof func === "function" && func() !== undefined ) { $element[0].style.position = "relative"; $scope.getPopupContainer()().appendChild(div); } else { document.body.appendChild(div); } $scope.state.popup = div; } $scope.state.open = !$scope.state.open; $scope.handleBlur(); }; }, require: ["?^esForm", "?^esFormItem"], link: function ( $scope, $element, $attrs, $controllers, $transclude ) { let [esForm, esFormItem] = $controllers; esNgAntd.createStyle("ant-select", style); if (esForm) { $scope.esForm = esForm.getContext(); $scope.esForm.state.formItems.push($scope); } if (esFormItem) { $scope.esFormItem = esFormItem.getContext(); } $timeout(function () { $scope.setValue($scope.value || $scope.defaultValue); }, 100); }, }; });