该组件在页面中使用方式
<auto-complete ng-model="result" init-list="mymenus" showkey="name" value="value" style="width:200px;margin-left:200px;"></auto-complete>
其中,ng-model为绑定在$scope的值,init-list为对象数组,showkey为对象中的显示的值的key,value为对象中的赋值的key,style为自定义内联样式。
假如以上参数如下:
$scope.mymenus = [{
name:"测试一",
value:"1"
},{
name:"试试一二",
value:"2"
},{
name:"测测二",
value:"3"
},{
name:"一二三四",
value:"4"
}]
$scope.result = "1"
展示如下:
样式仿照element-ui的带输入建议的input输入框 ,也可以自行修改样式
组件代码如下:
var autoComplete = {
restrict: 'E',
require: 'ngModel',
template:
`<div class="zq-auto-container" ng-style="zqWholeStyle">
<input class="zq-auto-input"
ng-model="zqInputValue"
ng-keyup="zqKeyupEvent()"
ng-focus="zqFocusEvent()"
ng-blur="zqBlurEvent($event)"
/>
<div class="zq-auto-items-container" ng-show="zqShowListDiv">
<ul>
<li class="zq-auto-items" ng-click="zqItemClick(item)" ng-repeat="item in zqItemList">
{{item[zqShowkey]}}
</li>
</ul>
</div>
</div>`,
// =表示共享某个变量 Two-way model binding
// &表示共享某个方法(回调) Callback method binding
// @表示传递某个值 Attribute string binding
scope: {
zqInitList: "=initList",//这里是父组件传过来的完整列表
zqResult: '=ngModel'//绑定父元素的ngmodel,
},
link: function ($scope, element, attrs) {
function addCss(style_text) {
var s = document.createElement('style');
s.innerText = style_text;
document.head.appendChild(s);
}
addCss(`
.zq-auto-container {
position: relative;
}`)
addCss(`
.zq-auto-input {
-webkit-appearance: none;
background-color: #fff;
background-image: none;
border-radius: 4px;
border: 1px solid #dcdfe6;
box-sizing: border-box;
color: #606266;
display: inline-block;
font-size: inherit;
height: 40px;
line-height: 40px;
outline: none;
padding: 0 15px;
}`)
addCss(`
.zq-auto-items-container {
max-height: 160px;
overflow-y: auto;
z-index: 9999;
position:absolute;
background: #FFFFFF;
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
border-radius: 4px;
border: 1px solid #e4e7ed;
-ms-overflow-style: none;
overflow: -moz-scrollbars-none;
}`)
//去掉滚动条宽度
addCss(`.zq-auto-items-container::-webkit-scrollbar { width: 0 !important }`)
addCss(`
.zq-auto-items-container ul{
margin:0;
padding:0;
}`)
addCss(`
.zq-auto-items {
min-width: 120px;
list-style-type: none;
padding: 0 20px;
margin: 0;
line-height: 34px;
cursor: pointer;
color: #606266;
font-size: 14px;
list-style: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}`)
//添加hover伪类
addCss(`
.zq-auto-items:hover {
color:#ffffff;
background-color:#2d9cf2;
}`)
//用于显示的key,默认是name
$scope.zqShowkey = attrs.showkey || "name";
//用于默认值的key
$scope.zqValue = attrs.value || "value";
//外面的样式
$scope.zqWholeStyle = formatStyle(attrs.style);
//输入框的值
$scope.zqInputValue = "";
//初始化输入框
$scope.zqInitList.forEach(function (item) {
if (item[$scope.zqValue] == $scope.zqResult) {
$scope.zqInputValue = item[$scope.zqShowkey];
}
})
//是初始化或者手工选取数据
$scope.zqValueHandler = true;
//监听输入框的值
$scope.$watch('zqInputValue', function (newVal, o, s) {
console.log("watch zqInputValue=", $scope.zqInputValue)
if (!$scope.zqValueHandler || !newVal) {//不是手工选数据或者没有数据,调用search方法
zqSearch()
} else if ($scope.zqValueHandler) {//是手工选数据,不做响应
$scope.zqValueHandler = false;
}
})
//是否显示list块
$scope.zqShowListDiv = false;
//渲染列表的值
$scope.zqItemList = [];
//鼠标点击在不在组件内,不在组件内,值为false,此时blur可用
$scope.zqInElement = false;
//鼠标点击事件
element.on("mousedown", function () {
//使得blur不可用
$scope.zqInElement = true;
})
//得到格式化过的style Obj
function formatStyle(str) {
var result = {};
var strArr = str.split(";");
strArr.forEach((style) => {
var styleArr = style.split(":");
if (styleArr.length == 2 && styleArr[0] && styleArr[1]) {
result[styleArr[0].trim()] = styleArr[1].trim();
}
})
return result;
}
//input失去焦点事件
$scope.zqBlurEvent = function (e) {
if (!$scope.zqInElement) {//如果不在组件内,则隐藏
$scope.zqShowListDiv = false;
}
//使blur可用
$scope.zqInElement = false;
}
//input获得焦点事件
$scope.zqFocusEvent = function () {
zqSearch();
//使blur可用
$scope.zqInElement = false;
}
//input案件弹起事件
$scope.zqKeyupEvent = function () {
console.log("keyup")
// zqSearch();
}
//点击选中事件
$scope.zqItemClick = function (item) {
$scope.zqInputValue = item[$scope.zqShowkey];
//给结果赋值
$scope.zqInitList.forEach(function (item) {
if (item[$scope.zqShowkey] == $scope.zqInputValue) {
$scope.zqResult = item[$scope.zqValue];
}
})
//隐藏list块
$scope.zqShowListDiv = false;
//使blur可用
$scope.zqInElement = false;
//手工选取标记
$scope.zqValueHandler = true;
}
function zqSearch() {
console.log("search", $scope.zqInputValue)
if ($scope.zqInputValue) {
$scope.zqItemList = $scope.zqInitList.filter(function (menu) {
return menu[$scope.zqShowkey].includes($scope.zqInputValue)
});
if ($scope.zqItemList.length == 0) {
$scope.zqResult = "";
}
} else {
$scope.zqItemList = $scope.zqInitList;
$scope.zqResult = "";
}
if ($scope.zqItemList && $scope.zqItemList.length > 0) {
$scope.zqShowListDiv = true;
}
}
}
};
注册该组件方法如下
app.directive('autoComplete', function(){
return autoComplete
})
其中,app为该页面angular1.x的实例。