Skip to main content

Angular NgZorro Integration

Introduction

NgZorro is a comprehensive UI component library for Angular based on the Ant Design system. It offers a wide range of high-quality components that help developers build elegant, consistent, and accessible web applications with minimal effort. By integrating NgZorro with your Angular project, you gain access to a rich ecosystem of pre-built components, from basic buttons and forms to complex date pickers, tables, and more.

In this tutorial, we'll explore how to integrate NgZorro into an Angular application and utilize some of its most popular components.

Why Choose NgZorro?

  • Enterprise-Grade Components: Built for business applications with complex UIs
  • Angular-First: Specifically designed for Angular, not a wrapper around vanilla JavaScript libraries
  • Internationalization: Supports multiple languages out of the box
  • Customizable Themes: Easy theming using less variables
  • Accessibility: Built with a11y in mind
  • Active Maintenance: Regular updates and strong community support

Prerequisites

Before we start, make sure you have:

  • Node.js (v12.x or later) and npm installed
  • Angular CLI installed (npm install -g @angular/cli)
  • Basic knowledge of Angular

Step 1: Create a New Angular Project

If you don't have an existing project, let's create one:

bash
ng new my-ngzorro-app
cd my-ngzorro-app

Step 2: Install NgZorro

Now, let's add NgZorro to our project:

bash
ng add ng-zorro-antd

This command will:

  • Install the NgZorro library and its dependencies
  • Add necessary styles and scripts to angular.json
  • Import NgZorro modules to app.module.ts
  • Set up internationalization
  • Add browser animations

When prompted, you can choose:

  • Whether to set up custom theme
  • Whether to use dark theme
  • Which locale to use (e.g., en_US)
  • Whether to set up automatically

Step 3: Configure NgZorro in Your Application

The ng add command should have already updated your app.module.ts. It should look something like this:

typescript
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

// NgZorro imports
import { NZ_I18N } from 'ng-zorro-antd/i18n';
import { en_US } from 'ng-zorro-antd/i18n';
import { registerLocaleData } from '@angular/common';
import en from '@angular/common/locales/en';

registerLocaleData(en);

@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule,
BrowserAnimationsModule
],
providers: [{ provide: NZ_I18N, useValue: en_US }],
bootstrap: [AppComponent]
})
export class AppModule {}

Step 4: Import Specific NgZorro Modules

NgZorro uses a modular approach, allowing you to import only the components you need. Let's import a few basic components:

typescript
// app.module.ts
import { NgModule } from '@angular/core';
// ... other imports

// NgZorro component modules
import { NzButtonModule } from 'ng-zorro-antd/button';
import { NzLayoutModule } from 'ng-zorro-antd/layout';
import { NzMenuModule } from 'ng-zorro-antd/menu';
import { NzIconModule } from 'ng-zorro-antd/icon';

@NgModule({
declarations: [AppComponent],
imports: [
// ... other imports
NzButtonModule,
NzLayoutModule,
NzMenuModule,
NzIconModule
],
providers: [{ provide: NZ_I18N, useValue: en_US }],
bootstrap: [AppComponent]
})
export class AppModule {}

Step 5: Create a Basic Layout

Let's update our app.component.html file to use NgZorro components for a basic layout:

html
<nz-layout>
<nz-header>
<div class="logo"></div>
<ul nz-menu nzTheme="dark" nzMode="horizontal">
<li nz-menu-item nzSelected>Home</li>
<li nz-menu-item>Products</li>
<li nz-menu-item>About</li>
<li nz-menu-item>Contact</li>
</ul>
</nz-header>
<nz-content>
<div class="inner-content">
<h1>Welcome to NgZorro!</h1>
<p>This is a basic layout example using NgZorro components.</p>
<div class="button-demo">
<button nz-button nzType="primary">Primary Button</button>
<button nz-button nzType="default">Default Button</button>
<button nz-button nzType="dashed">Dashed Button</button>
<button nz-button nzType="text">Text Button</button>
<button nz-button nzType="link">Link Button</button>
</div>
</div>
</nz-content>
<nz-footer>Angular NgZorro Demo ©2023</nz-footer>
</nz-layout>

Add some basic styling in app.component.css:

css
.logo {
width: 120px;
height: 31px;
background: rgba(255, 255, 255, 0.2);
margin: 16px 28px 16px 0;
float: left;
}

nz-header {
position: fixed;
width: 100%;
z-index: 1;
}

nz-content {
padding: 0 50px;
margin-top: 64px;
}

.inner-content {
background: #fff;
padding: 24px;
min-height: 280px;
}

nz-footer {
text-align: center;
}

.button-demo {
margin-top: 20px;
}

.button-demo button {
margin-right: 8px;
margin-bottom: 12px;
}

Step 6: Run Your Application

Now let's see our NgZorro application in action:

bash
ng serve

Visit http://localhost:4200 in your browser, and you should see your application with the NgZorro components.

Real-World Example: Creating a User Registration Form

Let's create a more practical example using NgZorro components. We'll build a user registration form with validation:

First, import the necessary modules in app.module.ts:

typescript
import { ReactiveFormsModule } from '@angular/forms';
import { NzFormModule } from 'ng-zorro-antd/form';
import { NzInputModule } from 'ng-zorro-antd/input';
import { NzSelectModule } from 'ng-zorro-antd/select';
import { NzDatePickerModule } from 'ng-zorro-antd/date-picker';
import { NzCheckboxModule } from 'ng-zorro-antd/checkbox';

@NgModule({
// ...
imports: [
// ... other imports
ReactiveFormsModule,
NzFormModule,
NzInputModule,
NzSelectModule,
NzDatePickerModule,
NzCheckboxModule
],
})
export class AppModule { }

Now, let's update our component class in app.component.ts:

typescript
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { NzFormTooltipIcon } from 'ng-zorro-antd/form';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
registerForm: FormGroup;

// For the select dropdown
listOfOption = [
{ label: 'Software Development', value: 'dev' },
{ label: 'Design', value: 'design' },
{ label: 'Marketing', value: 'marketing' },
{ label: 'Sales', value: 'sales' },
{ label: 'Other', value: 'other' }
];

submitForm(): void {
if (this.registerForm.valid) {
console.log('Form submitted:', this.registerForm.value);
// Here you would typically send the form to your backend
} else {
Object.values(this.registerForm.controls).forEach(control => {
if (control.invalid) {
control.markAsDirty();
control.updateValueAndValidity({ onlySelf: true });
}
});
}
}

constructor(private fb: FormBuilder) {}

ngOnInit(): void {
this.registerForm = this.fb.group({
email: [null, [Validators.required, Validators.email]],
password: [null, [Validators.required, Validators.minLength(6)]],
confirmPassword: [null, [Validators.required]],
name: [null, [Validators.required]],
phoneNumber: [null, [Validators.pattern(/^\d{10}$/)]],
department: [null, [Validators.required]],
birthday: [null],
agree: [false, [Validators.requiredTrue]]
});
}

validateConfirmPassword(): void {
setTimeout(() => {
const { password, confirmPassword } = this.registerForm.controls;
if (confirmPassword.value) {
if (password.value !== confirmPassword.value) {
confirmPassword.setErrors({ passwordMismatch: true });
} else {
confirmPassword.setErrors(null);
}
}
});
}
}

Finally, update the HTML template in app.component.html:

html
<nz-layout>
<nz-content>
<div class="registration-container">
<h1>User Registration</h1>

<form nz-form [formGroup]="registerForm" (ngSubmit)="submitForm()">
<!-- Email -->
<nz-form-item>
<nz-form-label [nzSpan]="6" nzRequired nzFor="email">E-mail</nz-form-label>
<nz-form-control [nzSpan]="14" nzErrorTip="Please enter a valid email!">
<input nz-input formControlName="email" id="email" />
</nz-form-control>
</nz-form-item>

<!-- Password -->
<nz-form-item>
<nz-form-label [nzSpan]="6" nzRequired nzFor="password">Password</nz-form-label>
<nz-form-control [nzSpan]="14" nzErrorTip="Please enter at least 6 characters!">
<input
nz-input
type="password"
formControlName="password"
id="password"
(ngModelChange)="validateConfirmPassword()"
/>
</nz-form-control>
</nz-form-item>

<!-- Confirm Password -->
<nz-form-item>
<nz-form-label [nzSpan]="6" nzRequired nzFor="confirmPassword">Confirm Password</nz-form-label>
<nz-form-control [nzSpan]="14" [nzErrorTip]="passwordErrorTpl">
<input
nz-input
type="password"
formControlName="confirmPassword"
id="confirmPassword"
/>
<ng-template #passwordErrorTpl let-control>
<ng-container *ngIf="control.hasError('required')">
Please confirm your password!
</ng-container>
<ng-container *ngIf="control.hasError('passwordMismatch')">
Passwords do not match!
</ng-container>
</ng-template>
</nz-form-control>
</nz-form-item>

<!-- Name -->
<nz-form-item>
<nz-form-label [nzSpan]="6" nzRequired nzFor="name">Full Name</nz-form-label>
<nz-form-control [nzSpan]="14" nzErrorTip="Please enter your name!">
<input nz-input formControlName="name" id="name" />
</nz-form-control>
</nz-form-item>

<!-- Phone Number -->
<nz-form-item>
<nz-form-label [nzSpan]="6" nzFor="phoneNumber">Phone Number</nz-form-label>
<nz-form-control [nzSpan]="14" nzErrorTip="Please enter a valid 10-digit phone number!">
<input nz-input formControlName="phoneNumber" id="phoneNumber" />
</nz-form-control>
</nz-form-item>

<!-- Department -->
<nz-form-item>
<nz-form-label [nzSpan]="6" nzRequired nzFor="department">Department</nz-form-label>
<nz-form-control [nzSpan]="14" nzErrorTip="Please select your department!">
<nz-select formControlName="department" id="department">
<nz-option
*ngFor="let option of listOfOption"
[nzLabel]="option.label"
[nzValue]="option.value">
</nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>

<!-- Birthday -->
<nz-form-item>
<nz-form-label [nzSpan]="6" nzFor="birthday">Date of Birth</nz-form-label>
<nz-form-control [nzSpan]="14">
<nz-date-picker formControlName="birthday" id="birthday"></nz-date-picker>
</nz-form-control>
</nz-form-item>

<!-- Agreement -->
<nz-form-item>
<nz-form-control [nzSpan]="14" [nzOffset]="6" nzErrorTip="You must agree to the terms!">
<label nz-checkbox formControlName="agree">
I have read and agree to the <a href="#">Terms of Service</a>
</label>
</nz-form-control>
</nz-form-item>

<!-- Submit Button -->
<nz-form-item>
<nz-form-control [nzSpan]="14" [nzOffset]="6">
<button nz-button nzType="primary">Register</button>
</nz-form-control>
</nz-form-item>
</form>
</div>
</nz-content>
</nz-layout>

Add the following CSS styles to app.component.css:

css
.registration-container {
max-width: 800px;
margin: 64px auto;
background: #fff;
padding: 24px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
}

h1 {
text-align: center;
margin-bottom: 24px;
}

[nz-form] {
max-width: 600px;
}

button[nz-button] {
margin-right: 8px;
}

Advanced Features

NgZorro offers many advanced features and components. Here's a brief overview:

1. Theming

You can customize the theme by modifying the variables in your src/theme.less file (created during installation):

less
// Override default variables
@primary-color: #1890ff;
@link-color: #1890ff;
@success-color: #52c41a;
@warning-color: #faad14;
@error-color: #f5222d;

2. Internationalization

NgZorro provides built-in support for multiple languages:

typescript
// Change to zh_CN (Chinese)
import { NZ_I18N, zh_CN } from 'ng-zorro-antd/i18n';
import { registerLocaleData } from '@angular/common';
import zh from '@angular/common/locales/zh';

registerLocaleData(zh);

@NgModule({
// ...
providers: [
{ provide: NZ_I18N, useValue: zh_CN }
]
})

3. Dynamic Components

NgZorro provides services for creating dynamic components like notifications, modals, and drawers:

typescript
import { NzModalService } from 'ng-zorro-antd/modal';
import { NzNotificationService } from 'ng-zorro-antd/notification';

constructor(
private modal: NzModalService,
private notification: NzNotificationService
) {}

showModal(): void {
this.modal.create({
nzTitle: 'Modal Title',
nzContent: 'Modal Content',
nzFooter: [
{
label: 'Cancel',
onClick: () => console.log('Cancel clicked')
},
{
label: 'OK',
type: 'primary',
onClick: () => console.log('OK clicked')
}
]
});
}

showNotification(): void {
this.notification.success(
'Success',
'Operation completed successfully!'
);
}

Summary

In this tutorial, we've covered:

  1. Installing and configuring NgZorro in an Angular application
  2. Using basic layout components to structure your application
  3. Creating a practical form with validation using NgZorro form components
  4. Exploring advanced features like theming and internationalization

NgZorro provides a rich ecosystem of components that follow the Ant Design principles. With its modular architecture, you can choose only the components you need, reducing bundle size. The library is well-documented and actively maintained, making it an excellent choice for building enterprise-grade Angular applications.

Additional Resources

Exercises

  1. Create a data table using the NgZorro nz-table component with sorting and pagination
  2. Build a dashboard layout with a side navigation menu using nz-layout, nz-sider, and nz-menu
  3. Implement a search form with auto-complete functionality using NgZorro components
  4. Create a multi-step form wizard using the nz-steps component
  5. Build a responsive card gallery using nz-card and CSS Grid/Flexbox

By completing these exercises, you'll gain practical experience with some of NgZorro's most powerful components, setting you on the path to creating sophisticated Angular applications.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)