AngularJS Ng-repeat分组过滤及Azure服务器日志数组排序需求
Hey there! Let's tackle this problem step by step—first we'll get your Azure Application Insights click data sorted, then we'll implement the grouping and filtering with AngularJS's ng-repeat.
Step 1: Fetch & Sort Your Azure Logs Data
Your existing $http call is on the right track, but we can optimize sorting directly in the Kusto query (it’s way more efficient than sorting client-side for large datasets). Here’s how to adjust your request to return pre-sorted results:
Updated $http Request
$http({ method: 'Get', headers: { 'Host': 'api.applicationinsights.io', 'x-api-key': 'xxxxxxxxxxxxxx' // Pro tip: Store this in an environment variable, never hard-code it! }, url: 'https://api.applicationinsights.io/v1/apps/20exxxx-xxxx-xxxx-xxxx-cf8bc569d261/query?query=' + encodeURIComponent( 'requests | where timestamp > datetime(2018-03-13) and timestamp <= datetime(2018-03-22) + 1d | where name contains "GetCode" | where name contains "9278" | sort by timestamp desc' ) }) .success(function (data) { // Convert the API's table-style response to a clean object array $scope.clicks = data.tables[0].rows.map(row => { // Map columns to meaningful keys (adjust based on your actual log fields) return { timestamp: row[0], name: row[1], url: row[2], duration: row[3] }; }); // Fallback for client-side sorting if needed: // $scope.clicks.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp)); });
- The
sort by timestamp descclause in the Kusto query returns results from newest to oldest. Swapdesctoascif you want oldest first. encodeURIComponent()ensures the query string is safely passed in the URL.- We map the API’s table rows to a readable object array for easier use in AngularJS templates.
Step 2: AngularJS ng-repeat Grouping & Filtering
AngularJS doesn’t have a built-in grouping filter, but we can create a custom one. We’ll also use the built-in filter directive for search/filtering.
1. Create a Custom GroupBy Filter
Add this to your AngularJS module to enable grouping functionality:
angular.module('yourAppName') .filter('groupBy', function() { return function(collection, groupField) { if (!collection || !groupField) return collection; const groupedData = {}; collection.forEach(item => { const groupKey = item[groupField]; if (!groupedData[groupKey]) { groupedData[groupKey] = []; } groupedData[groupKey].push(item); }); return groupedData; }; });
2. Combine Filtering & Grouping in Your Template
Here’s how to add a search filter and display grouped results in your HTML:
<!-- Search Filter Input --> <input type="text" ng-model="searchQuery" placeholder="Search clicks by name/URL..."> <!-- Grouped & Filtered Results --> <div ng-repeat="(groupName, groupItems) in clicks | filter: searchQuery | groupBy: 'name'"> <h3>{{ groupName }}</h3> <ul> <li ng-repeat="click in groupItems"> <strong>Time:</strong> {{ click.timestamp | date:'medium' }}<br> <strong>URL:</strong> {{ click.url }}<br> <strong>Duration:</strong> {{ click.duration }}ms </li> </ul> </div>
filter: searchQueryautomatically filters theclicksarray against the input text (matches any field by default; usefilter: {name: searchQuery}to target specific fields only).groupBy: 'name'groups filtered results by thenamefield—replace this with any field you want (e.g., formattimestampto a date string first if grouping by day).
Bonus: Custom Filter for Advanced Control
If you need precise filtering rules (e.g., only match partial strings in specific fields), add a filter function to your controller:
$scope.filterClicks = function(click) { if (!$scope.searchQuery) return true; const query = $scope.searchQuery.toLowerCase(); return click.name.toLowerCase().includes(query) || click.url.toLowerCase().includes(query); };
Then use it in the template:
<div ng-repeat="(groupName, groupItems) in clicks | filter: filterClicks | groupBy: 'name'"> <!-- ... same result layout ... --> </div>
内容的提问来源于stack exchange,提问作者Ewald Bos

