我正在使用Angular Material进行自定义自动完成,我想将自动完成下拉结果框的高度设置为更大的值。
为了达到这个目的,我做了一个研究并得出结论,Angular Material不支持这个,并且这个问题只会在Angular Material 2中解决(将发布给AngularJS2):
阅读后,我意识到有些人找到了解决这个限制的方法(Angular Material Design Layout custom sizes),但无论我尝试什么,我都可以看到他们的任何建议都有效。< / p>
我的示例应用程序由index.html
,autocomplete.js
文件和带有mockData.json文件的server.js
文件组成。
以下是index.html
,autocomplete.js
和style.css
个文件。由于我在Cloud9中托管此示例,如果服务器处于开启状态,您可以看到它正在运行!
/*global angular*/
"use strict";
angular.module('MyApp', ['ngMaterial', 'ngMessages', 'material.svgAssetsCache', 'ngMdIcons']).controller('DemoCtrl', DemoCtrl);
function DemoCtrl($q, $log, $http) {
this.searchText = null;
this.querySearch = function(query) {
let serverUrl = '//custom-material-autocomplete-fl4m3ph03n1x.c9users.io/getClients';
let deferred = $q.defer();
$http({
method: 'GET',
url: serverUrl,
params: {
word: query
}
}).then(function successCallback(response) {
deferred.resolve(response.data);
}, function errorCallback(response) {
$log.error(response);
});
return deferred.promise;
};
this.searchTextChange = function(text) {
$log.info('Text changed to ' + text);
}
this.selectedItemChange = function(item) {
$log.info('Item changed to ' + JSON.stringify(item));
}
}
&#13;
.autocompletedemoCustomTemplate .autocomplete-custom-template li {
border-bottom: 1px solid #ccc;
height: auto;
padding-top: 8px;
padding-bottom: 8px;
white-space: normal;
}
.autocompletedemoCustomTemplate .autocomplete-custom-template li:last-child {
border-bottom-width: 0;
}
.autocompletedemoCustomTemplate .autocomplete-custom-template .item-title,
.autocompletedemoCustomTemplate .autocomplete-custom-template .item-metadata {
display: block;
line-height: 2;
}
.autocompletedemoCustomTemplate .autocomplete-custom-template .item-title md-icon {
height: 18px;
width: 18px;
}
&#13;
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body ng-app="MyApp" ng-cloak>
<div ng-controller="DemoCtrl as ctrl" layout="column" ng-cloak="" class="autocompletedemoCustomTemplate" ng-app="MyApp">
<md-content layout-padding="" layout="column">
<form ng-submit="$event.preventDefault()">
<md-autocomplete md-selected-item="ctrl.selectedItem" md-search-text-change="ctrl.searchTextChange(ctrl.searchText)" md-search-text="ctrl.searchText" md-selected-item-change="ctrl.selectedItemChange(item)" md-items="item in ctrl.querySearch(ctrl.searchText)"
md-item-text="item.name" md-min-length="0" placeholder="Pick an Angular repository" md-menu-class="autocomplete-custom-template">
<md-item-template>
<span class="item-title">
<strong>Company name:</strong> {{item.Company_Name}}
</span>
<strong>Client Ids:</strong>
<span ng-repeat="clientId in item.Assets">
<span class="item-metadata">
<span class="item-metastat">
 <ng-md-icon icon="subdirectory_arrow_right" style="fill: gray" size="24"></ng-md-icon>
{{clientId}}
</span>
</span>
</span>
</md-item-template>
</md-autocomplete>
</form>
</md-content>
</div>
<!--CSS files-->
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0-rc4/angular-material.min.css">
<link rel="stylesheet" href="https://material.angularjs.org/1.1.0-rc4/docs.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic">
<link rel="stylesheet" href="/css/style.css">
<!-- Angular Material requires Angular.js Libraries -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-route.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-aria.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-messages.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-114/svg-assets-cache.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0-rc4/angular-material.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-material-icons/0.7.0/angular-material-icons.min.js"></script>
<!-- Your application bootstrap -->
<script type="text/javascript" src="js/autocomplete.js"></script>
</body>
</html>
&#13;
以下是server.js
文件和mockData.json文件。
"use strict";
//Lets define a port we want to listen to
const PORT = 8080;
//Init Vars
var express = require('express');
var fs = require('fs');
var app = express();
//Init Functions
//we allow CORS: http://enable-cors.org/server_expressjs.html
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.listen(PORT, function() {
console.log('Example app listening on port ' + PORT + '!');
});
//GET methods
app.get('/getClients', function(req, res, next) {
let assetsQuery = function(array, word) {
let result = false;
array.forEach(function(element, index, array) {
if (element.toLowerCase().trim().includes(word))
result = true;
});
return result;
};
//get parameters from GET: https://scotch.io/tutorials/use-expressjs-to-get-url-and-post-parameters
var query = req.param('word');
let dbQuery = JSON.parse(fs.readFileSync('mockData.json', 'utf8'));
let result = [];
if (query == null || query == "" || typeof query == 'undefined')
result = dbQuery.mockupData;
else {
query = query.toLowerCase().trim();
dbQuery.mockupData.forEach(function(element, index, array) {
if (element.Company_Name.toLowerCase().trim().includes(query) || assetsQuery(element.Assets, query))
result.push(element);
});
}
res.send(result);
});
虚假数据文件:
{
"mockupData": [{
"AccountID": "cweu4xy733z06mqv96",
"Company_Name": "Wal - Mart Stores, Inc",
"Assets": ["gme-wal1", "gme-wal2"]
}, {
"AccountID": "3tvjnjzud1jz2xy6ug",
"Company_Name": "Volkswagen Automotive",
"Assets": ["gme-vol1", "gme-aut2"]
}, {
"AccountID": "ht019dupmtb4jinzpo",
"Company_Name": "Vitol Commodities",
"Assets": ["gme-vit1", "gme-com2"]
}, {
"AccountID": "l2fd73rbpc48d1hvua",
"Company_Name": "Verizon Telecommunications",
"Assets": ["gme-ver1", "gme-tel2"]
}, {
"AccountID": "2iygtyj2do2pi8e4dv",
"Company_Name": "Valero",
"Assets": ["gme-vale1", "gme-valoil2"]
}, {
"AccountID": "1ojav89f9qka85vpwb",
"Company_Name": "United Health Health care",
"Assets": ["gme-usahc1", "gme-uhhc2"]
}, {
"AccountID": "y9ikfaj2qgf18d0vsw",
"Company_Name": "Trafigura Commodities",
"Assets": ["gme-traf1", "gme-trafcom2"]
}, {
"AccountID": "nxhpt5unxsjedui5sk",
"Company_Name": "Toyota Automotive",
"Assets": ["gme-toy1", "gme-oyota2"]
}, {
"AccountID": "hqu18f8wy43oc5kfde",
"Company_Name": "Total",
"Assets": ["gme-total1", "gme-tot2"]
}, {
"AccountID": "tsc9aures3yjpy2nrr",
"Company_Name": "Tata Group Conglomerate",
"Assets": ["gme-tata1", "gme-grcon2"]
}, {
"AccountID": "paoxb086omzi1uu5zr",
"Company_Name": "State Grid Electric utility",
"Assets": ["gme-sgeu1", "gme-elecs2"]
}, {
"AccountID": "7u2fhcatofgqjzv2tf",
"Company_Name": "Sinopec Group",
"Assets": ["gme-sin1", "gme-sinoil2"]
}, {
"AccountID": "hbg285h3nk206zmdqb",
"Company_Name": "Saudi Aramco",
"Assets": ["gme-sau1", "gme-aram2"]
}, {
"AccountID": "xyg1n25grvl74f69l6",
"Company_Name": "Samsung Conglomerate",
"Assets": ["gme-sam1", "gme-sacomg2"]
}, {
"AccountID": "aaoexfcqln8peec4dv",
"Company_Name": "Royal Dutch Shell",
"Assets": ["gme-royal1", "gme-forthequeen"]
}, {
"AccountID": "rubvrmy2ucrvh3elrj",
"Company_Name": "Phillips 66",
"Assets": ["gme-phil1", "gme-ips2"]
}, {
"AccountID": "5gmxscwazuokverzbd",
"Company_Name": "Petrobras",
"Assets": ["gme-pedro1", "gme-petro2"]
}, {
"AccountID": "nsx4y558obp62dwn47",
"Company_Name": "PDVSA",
"Assets": ["gme-pdvsa1", "gme-pgas"]
}, {
"AccountID": "80o7d5p4wrx1ueygmx",
"Company_Name": "Microsoft Conglomerate",
"Assets": ["gme-microsoft1", "gme-evil2"]
}, {
"AccountID": "1v14j9i5w8sy4iipuv",
"Company_Name": "McKesson Pharmaceuticals",
"Assets": ["gme-mckesson1", "gme-mckeuticals2"]
}, {
"AccountID": "92ac8fl1dk1nh5v408",
"Company_Name": "Lukoil",
"Assets": ["gme-luko1", "gme-loil2"]
}, {
"AccountID": "pn3w8dxqrzytlmanhe",
"Company_Name": "Kuwait Petroleum Corporation",
"Assets": ["gme-kuwait1", "gme-war2"]
}, {
"AccountID": "35mtlyc6bnbxhuav1d",
"Company_Name": "Koch Industries Conglomerate",
"Assets": ["gme-koch1", "gme-kindus2"]
}, {
"AccountID": "n4gu863njqnndvmk3d",
"Company_Name": "Japan Post Conglomerate",
"Assets": ["gme-jap1", "gme-konichiwa2"]
}, {
"AccountID": "gkrllbxd56r9gi4q7t",
"Company_Name": "Industrial and Commercial Bank of China Financial services",
"Assets": ["gme-china1", "gme-LongLiveTsungLee2"]
}, {
"AccountID": "qgb1gudy460seqgzo3",
"Company_Name": "Honda Automotive",
"Assets": ["gme-honhon1", "gme-autohon2"]
}]
}
如何让我的下拉框更大?
答案 0 :(得分:4)
您可以使用未记录的参数md-dropdown-items
:
<md-autocomplete
md-selected-item="selectedItem"
md-search-text="searchText"
md-items="item in getMatches(searchText)"
md-item-text="item.display"
md-dropdown-items="10">
<span md-highlight-text="searchText">{{item.display}}</span>
</md-autocomplete>
默认值为5(版本为angular-material#ad0581ddd3)。
您可能还想根据窗口的高度调整此值:
<md-autocomplete
md-selected-item="selectedItem"
md-search-text="searchText"
md-items="item in getMatches(searchText)"
md-item-text="item.display"
md-dropdown-items="nbItems">
<span md-highlight-text="searchText">{{item.display}}</span>
</md-autocomplete>
然后在控制器中设置nbItems
。例如:
$scope.nbItems = 5 + $mdMedia('(min-height: 400px)') * 5 + $mdMedia('(min-height: 600px)') * 10;
因此,如果高度低于400px,则将有5个项目,如果低于600px,则将有10个项目,如果高于600px,则将有20个项目。
希望有所帮助
注意:md-dropdown-items
的{{1}}参数不存在,仅适用于md-select
。
太糟糕了;)
答案 1 :(得分:3)
经过多次实验和阅读,我终于找到了解决方法。
我的解决方案并不是解决问题的方法,而是更多的黑客攻击。事实上,没有官方的支持,至少在Angular Material 1中,永远不会有为了制作Angular Material 2而被弃用的东西,并且已经失去官方支持。
因此,我的解决方法集中在github中找到的一个建议,它有效地覆盖了默认的CSS:
.md-virtual-repeat-container.md-autocomplete-suggestions-container {
height: 24vh;
min-height: 12vh;
max-height: 24vh !important;
}
此代码使用!important
覆盖默认CSS并设置自定义高度。在这种情况下,我使用vh
测量,但您可以使用px
或任何其他。
如果您只有一个带下拉框的自动填充功能,或者所有带有下拉框的自动填充功能相同,则此变通方法可以正常工作。
但是,如果您有两个彼此不同的自动填充,则由于覆盖(将影响所有自动填充),您将开始使用自己的代码。
最后,这不是一个完美的解决方案,但只要你不做太多的自动完成,它应该没问题。
我希望这可以帮助将来的某个人!