| name | delon-util |
| description | @delon/util skill - Utility functions library for array, string, date, number manipulation. For ng-events construction site progress tracking system. |
@delon/util - Utility Functions Library
Trigger patterns: "utility", "helper", "@delon/util", "format", "deepCopy", "deepMerge"
Overview
@delon/util provides a comprehensive collection of utility functions for common data manipulation tasks in ng-alain applications.
Package: @delon/util@20.1.0
Categories
1. Array Utilities (array/)
deepCopy - Deep Copy Arrays/Objects
import { deepCopy } from '@delon/util/array';
const original = { name: '任務', items: [1, 2, 3], meta: { id: 1 } };
const copy = deepCopy(original);
copy.items.push(4);
console.log(original.items);
console.log(copy.items);
Use Cases:
- Clone state objects for immutability
- Create independent copies before mutations
- Deep cloning form data
deepMerge - Deep Merge Objects
import { deepMerge } from '@delon/util/array';
const defaults = {
config: { theme: 'light', size: 'default' },
features: ['dashboard']
};
const custom = {
config: { theme: 'dark' },
features: ['reports']
};
const merged = deepMerge(defaults, custom);
Other Array Functions
import {
groupBy,
uniq,
uniqBy,
orderBy
} from '@delon/util/array';
const grouped = groupBy(tasks, 'status');
const uniqueIds = uniq([1, 2, 2, 3]);
const uniqueTasks = uniqBy(tasks, 'id');
const sorted = orderBy(tasks, ['priority', 'createdAt'], ['asc', 'desc']);
2. String Utilities (string/)
format - String Formatting
import { format } from '@delon/util/string';
const message = format('任務 {0} 已指派給 {1}', taskName, userName);
const message2 = format('任務 {name} 的狀態為 {status}', {
name: '地基施工',
status: '進行中'
});
Other String Functions
import {
toCamelCase,
toPascalCase,
toKebabCase,
toSnakeCase,
truncate
} from '@delon/util/string';
toCamelCase('task-name');
toPascalCase('task-name');
toKebabCase('TaskName');
toSnakeCase('TaskName');
truncate('Long text...', 10);
3. Date Utilities (date/)
getTimeDistance - Get Time Ranges
import { getTimeDistance } from '@delon/util/date';
const today = getTimeDistance('today');
const week = getTimeDistance('week');
const month = getTimeDistance('month');
const year = getTimeDistance('year');
const lastWeek = getTimeDistance('week', -1);
Supported Types:
'today' - Current day
'week' - Current week (Sunday to Saturday)
'month' - Current month
'year' - Current year
- Custom offset (negative for past, positive for future)
formatDistanceToNow - Relative Time
import { formatDistanceToNow } from '@delon/util/date';
const createdAt = new Date('2024-12-20');
const relative = formatDistanceToNow(createdAt);
const futureDate = new Date('2024-12-30');
const future = formatDistanceToNow(futureDate);
4. Number Utilities (number/)
currency - Currency Formatting
import { currency } from '@delon/util/number';
currency(1234567.89);
currency(1234567.89, { unit: '¥' });
currency(1234.5, { precision: 0 });
Other Number Functions
import {
toFixed,
toPercent,
toThousands
} from '@delon/util/number';
toFixed(1.2345, 2);
toPercent(0.1234);
toPercent(0.1234, 1);
toThousands(1234567);
5. Browser Utilities (browser/)
copyToClipboard - Copy to Clipboard
import { copy } from '@delon/util/browser';
async copyTaskLink(taskId: string) {
const link = `${window.location.origin}/tasks/${taskId}`;
const success = await copy(link);
if (success) {
this.messageService.success('連結已複製');
} else {
this.messageService.error('複製失敗');
}
}
Other Browser Functions
import {
scrollToTop,
deepGet,
deepSet,
isEmpty,
isEqual,
updateHostClass
} from '@delon/util/browser';
scrollToTop();
scrollToTop({ duration: 500 });
const value = deepGet(obj, 'user.profile.name');
deepSet(obj, 'user.profile.name', 'New Name');
isEmpty(null);
isEmpty('');
isEmpty([]);
isEmpty({});
isEqual({ a: 1 }, { a: 1 });
Real-World Examples
Task Management Utilities
import { Component, signal, computed, inject } from '@angular/core';
import { deepCopy, groupBy, orderBy } from '@delon/util/array';
import { format } from '@delon/util/string';
import { getTimeDistance } from '@delon/util/date';
import { copy } from '@delon/util/browser';
import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
selector: 'app-task-list',
standalone: true,
template: `
<nz-card>
<div nz-row [nzGutter]="16">
@for (group of groupedTasks() | keyvalue; track group.key) {
<div nz-col [nzSpan]="8">
<h3>{{ group.key }} ({{ group.value.length }})</h3>
@for (task of group.value; track task.id) {
<nz-card>
<h4>{{ task.title }}</h4>
<p>{{ formatTaskInfo(task) }}</p>
<button nz-button (click)="copyTaskLink(task.id)">
複製連結
</button>
</nz-card>
}
</div>
}
</div>
</nz-card>
`
})
export class TaskListComponent {
private messageService = inject(NzMessageService);
tasks = signal<Task[]>([]);
groupedTasks = computed(() =>
groupBy(.(), )
);
sortedTasks = (
(
.(),
[, ],
[, ]
)
);
(: ): {
(
,
{
: task.,
: .(task.)
}
);
}
(: ): <> {
link = ;
success = (link);
(success) {
..();
} {
..();
}
}
(: ): {
(task);
}
(): [] {
[start, end] = ();
.().(
t. >= start && t. <= end
);
}
(: ): {
(
,
{
: date.(),
: (date.() + ).(, ),
: (date.()).(, )
}
);
}
}
Form Data Utilities
import { Component, signal } from '@angular/core';
import { deepCopy, deepMerge } from '@delon/util/array';
import { isEmpty } from '@delon/util/browser';
@Component({
selector: 'app-task-form',
standalone: true,
template: `
<form nz-form (ngSubmit)="handleSubmit()">
<!-- form fields -->
<button nz-button [disabled]="hasEmptyRequired()">
提交
</button>
</form>
`
})
export class TaskFormComponent {
private defaults = {
priority: 'medium',
status: 'pending',
assignee: null,
tags: []
};
formData = signal(deepCopy(this.defaults));
originalTask = signal<Task | null>(null);
loadTask(task: Task): void {
const merged = deepMerge(this., task);
..(merged);
..((task));
}
(): {
data = .();
(data.) || (data.);
}
(): {
original = .();
(!original) ;
!(original, .());
}
(): {
(!.()) {
submitData = (.());
}
}
}
Best Practices
1. Use Utilities for Immutability
✅ DO:
const taskCopy = deepCopy(task);
taskCopy.status = 'completed';
this.tasks.update(tasks => [...tasks, taskCopy]);
❌ DON'T:
task.status = 'completed';
this.tasks.update(tasks => [...tasks, task]);
2. Leverage Computed Signals with Utilities
✅ DO:
groupedTasks = computed(() => groupBy(this.tasks(), 'status'));
sortedTasks = computed(() => orderBy(this.tasks(), ['priority'], ['asc']));
3. Use Type-Safe Utilities
✅ DO:
import { deepCopy } from '@delon/util/array';
const copy: Task = deepCopy<Task>(originalTask);
Performance Considerations
- deepCopy: Expensive for large objects - use sparingly
- groupBy/orderBy: Wrap in computed() to avoid recalculation
- getTimeDistance: Cache results if used frequently
- copy: Async operation - handle loading states
Integration Checklist
Cross-References
- angular-component - Signals integration
- delon-form - Form utilities for validation
- firebase-repository - deepCopy for state management
Version: 1.0
Created: 2025-12-25
Maintainer: ng-events(GigHub) Development Team