Angular 实战教程 - 手把手教你构建待办事项应用 Today (Part 1)

简介:

5925441e2d2be595c1ea0450169c23e48d850511

01d8c98259a0afb07dfdfd37f07a2b5ab113a1c5

bdedcea41b36328310735f9249a42df640380f2a

这是什么?我适合阅读吗?

ng.ant.design/docs/introd…

NG-ZORRO 是由阿里巴巴阿里云和计算平台事业部的小伙伴为 Ant Design 开发的 Angular 版本,是一个适用于构建中后台应用的组件库。该系列文章是为 ng-zorro 的用户提供的教程项目 Today 的配套教程。如果你是新用户,想要了解一下 ng-zorro 的使用姿势,或者你是 Angular 初学者,想要通过一个项目来锻炼自己的开发能力,欢迎阅读。

目录和链接

本系列文章共有以下几篇(更新中):

  1. (本篇)项目简介,学习在项目中添加 ng-zorro,编写最简单的 setup(初始设置)界面

你可以点击下面的链接预览:

Today

点击下面的链接获取源代码:

today-ng

点击下面的链接获取按照行文顺序 commit 的源代码:

wendzhue/today-ng-steps

项目介绍

我们的教程项目要编写一个名为 Today 的待办事项应用。

Today 还有一个基于 electron 和 Vue 的版本,完成度比较高,建议你浏览 该项目的主页(对于 Mac 用户我们还提供了能直接运行的 dmg,其他平台的用户请自行 build)。

该应用主要包含以下几个界面,并提供如下的功能:

  • 主界面,分为左边的清单列表和右边的待办事项列表。除了最基本的增加、删除、重命名清单和待办事项外,我们还要支持改变待办事项的排序方法,特别的,我们还要提供“建议”帮助用户确定今天(或者说接下来)要做的事情
  • 待办详情界面:在用户点击一个待办事项之后,这个界面会弹出以让用户对改办事项进行更多的修改,包括修改截止时间、计划时间、待办标题、详情、是否需要提醒等等
  • 总结界面,我们帮助用户记录他们每一天完成任务的情况,并且通过日历的形式展示
  • 初始化(setup)界面
  • 设置界面

是不是有点期待了呢?我们现在就开始!


项目构建

想要了解更多关于项目构建的内容, 请阅读 ng-zorro 的文档

我们先构建一个新项目,然后在这个项目里安装 ng-zorro。


$ ng new today-ng
$ cd today-ng
$ ng add ng-zorro-antd

现在尝试 ng serve,并打开 locahost:4200,你应该可以看到 ng-zorro 的标志了,恭喜你顺利的为你的项目引入了 ng-zorro!

150e450da2d13a37a966d77cc4cc6e410b7d4d23

划分模块并设置路由

我们的应用分为好几个页面,为了在代码的层面也有对应的划分,并保持好的拓展性和可维护性,我们将每个大页面都划分为一个独立的模块。这篇文章里,我将会向你展示如何做最简单的一个模块 setup。

我们先创建 setup module 和对应的 component:


ng g m pages/setup
ng g c pages/setup --module pages/setup

给项目添加路由。创建 app/app-routing.module.ts 文件,然后编写如下内容:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { SetupComponent } from './pages/setup/setup.component';


const routes: Routes = [
  { path: 'setup', component: SetupComponent },
  { path: '', redirectTo: '/setup', pathMatch: 'full' }
];

@NgModule({
  imports: [ RouterModule.forRoot(routes) ],
  exports: [ RouterModule ]
})
export class AppRoutingModule {}

修改 app.module.ts 来引入 setup 以及路由模块:

// ...

import { AppRoutingModule } from './app-routing.module';
import { SetupModule } from './pages/setup/setup.module';

registerLocaleData(zh);

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

最后再更新 app.component.html 的内容为 <router-outlet></router-outlet>,这样,我们就划分好了第一个模块并处理了部分路由,现在请看浏览器,是不是显示 setup works! 了呢?

Setup 模块

89b0d2675ad7ec403df97e8add00cc7c5d2456b7

在我们开始写界面之前,先简单分析一下。显然,我们需要把用户名和初始化标记存入 local storage,也很显然,我们不应该把 localStorage.set 等代码直接下载组件文件中,一是因为其他 module 和 component 肯定也要访问用户名信息,二是这提高了代码的耦合性——如果我们切换了存储机制,我们需要到处修改——所以我们要在这里引入 local storage service。除此之外,既然多个 module 需要读取同一信息,我们就要对键值 key 做出约定。

想清楚了,我们再开始写代码,在命令行中输入:


$ ng g s services/local-storage --module app

然后在 local-storage.service.ts 中编码:


import { Injectable } from '@angular/core';

const ls = localStorage;

@Injectable()
export class LocalStorageService {
  constructor() { }

  public get<T>(key: string): any {
    return JSON.parse(ls.getItem(key)) as T;
  }

  public getList<T>(key: string) {
    const before = ls.getItem(key);
    return before ? (JSON.parse(before) as T[]) : [];
  }

  public set(key: string, value: any): void {
    if (!value && value === undefined) { return; }
    const arr = JSON.stringify(value);
    ls.setItem(key, arr);
  }
}

在 local-storage.service.ts 同目录下创建 local-storage.namespace.ts 文件(为了简化后面的教程,我这里就把后面会用到的键全告诉你了):


export const GLOBAL_NAMESPACE = 'today.';

export const APP_INFO_NAMESPACE = GLOBAL_NAMESPACE + 'appInfo.';
export const INIT_FLAG = APP_INFO_NAMESPACE + 'initFlag';
export const START_USING_DATE = APP_INFO_NAMESPACE + 'startUsingDate';

export const USER_INFO_NAMESPACE = GLOBAL_NAMESPACE + 'userInfo.';
export const USERNAME = USER_INFO_NAMESPACE + 'username';
export const AVATAR_CODE = USER_INFO_NAMESPACE + 'avatarCode';

export const TODO_NAMESPACE = GLOBAL_NAMESPACE + 'todo.';
export const TODOS = TODO_NAMESPACE + 'todos';

export const LIST_NAMESPACE = GLOBAL_NAMESPACE + 'list.';
export const LISTS = LIST_NAMESPACE + 'lists';

export const SUMMARY_NAMESPACE = GLOBAL_NAMESPACE + 'summary.';
export const LAST_SUMMARY_DATE = SUMMARY_NAMESPACE + 'lastSummaryDate';
export const SUMMARIES = SUMMARY_NAMESPACE + 'summaries';

在用 local storage 进行存储的时候使用命名空间是个最佳实践,命名空间可以是应用名加模块名等形式。

 

这样就搞定了 service 了,接下来写组件,在 setup.module.html 当中编写界面内容:


<div class="full-screen page-content">
  <div class="wrapper">
    <img class="logo-img" src="./assets/img/logo.png" alt="">
    <div class="text-wrapper">
      <h1 class="title-text">
        Today
      </h1>
    </div>
    <input nz-input placeholder="请输入你喜欢的用户名" #usernameInput [(ngModel)]="username">
    <button nz-button [nzType]="'primary'" (click)="completeSetup()" [disabled]="!usernameInput.value">
      开始
    </button>
    <div class="copy-right">
      Copyright © 2018 Wendell Hu
    </div>
  </div>
</div>

在 setup.module.ts 当中编写界面逻辑:


import { Component, HostBinding, OnInit } from '@angular/core';
import { LocalStorageService } from '../../services/local-storage/local-storage.service';
import {
  USERNAME,
  INIT_FLAG,
  START_USING_DATE
} from '../../services/local-storage/local-storage.namespace';
import { getTodayTime } from '../../../utils/time';

@Component({
  selector: 'app-setup',
  templateUrl: './setup.component.html',
  styleUrls: [ './setup.component.less' ]
})

export class SetupComponent implements OnInit {
  username: string;

  constructor(
    private store: LocalStorageService
  ) {
  }

  ngOnInit() {
  }

  completeSetup(): void {
    this.store.set(INIT_FLAG, true);
    this.store.set(START_USING_DATE, getTodayTime());
    this.store.set(USERNAME, this.username);
  }
}

完成(CSS 请自行编写,推荐使用 CSS 的各种预处理器)!你可以在这个界面输入用户名,点击按钮之后,你就能在 local storage 检视面板中看到有三个字段存储了值。

559c52f4d95911b7e215bdff8f383fb94174d955
原文发布时间为:2018年06月02日
本文来源: 掘金     如需转载请联系原作者


相关文章
|
4月前
|
缓存 JavaScript 前端开发
Angular 应用打包和部署
Angular 应用打包和部署
210 58
|
3月前
|
缓存 监控 JavaScript
Angular 应用打包和部署
【10月更文挑战第16天】Angular 应用的打包和部署是一个综合性的过程,需要考虑多个方面的因素。通过合理的打包和部署策略,可以确保应用在生产环境中稳定运行,并为用户提供良好的体验。你需要根据实际情况选择合适的部署方式,并不断优化和改进部署流程,以适应业务的发展和变化。
|
5月前
|
前端开发 开发者 开发框架
JSF与Bootstrap,打造梦幻响应式网页!让你的应用跨设备,让用户爱不释手!
【8月更文挑战第31天】在现代Web应用开发中,响应式设计至关重要,以确保不同设备上的良好用户体验。本文探讨了JSF(JavaServer Faces)与Bootstrap框架的结合使用,展示了如何构建响应式网页。JSF是一个基于Java的Web应用框架,提供丰富的UI组件和表单处理功能;而Bootstrap则是一个基于HTML、CSS和JavaScript的前端框架,专注于实现响应式设计。通过结合两者的优势,开发者能够更便捷地创建自适应布局,提升Web应用体验。然而,这种组合也有其局限性,如JSF组件库较小和较高的学习成本等,因此在选择开发框架时需综合考虑具体需求和应用场景。
60 0
|
5月前
|
前端开发 Java UED
JSF遇上Material Design:一场视觉革命,如何让传统Java Web应用焕发新生?
【8月更文挑战第31天】在当前的Web开发领域,用户体验和界面美观性至关重要。Google推出的Material Design凭借其独特的动画、鲜艳的颜色和简洁的布局广受好评。将其应用于JavaServer Faces(JSF)项目,能显著提升应用的现代感和用户交互体验。本文介绍如何通过PrimeFaces等组件库在JSF应用中实现Material Design风格,包括添加依赖、使用组件及响应式布局等步骤,为用户提供美观且功能丰富的界面。
59 0
|
5月前
|
应用服务中间件 Java Maven
掌控视图的力量!深入解析 JSF 视图管理,揭秘视图生命周期的秘密,让你的应用更高效!
【8月更文挑战第31天】JavaServer Faces (JSF) 是一种强大的框架,用于管理 Web 应用程序的视图。本文通过具体案例介绍 JSF 视图管理的基础知识,包括创建、管理和销毁视图的过程。首先,在 Eclipse 中创建一个新 JSF 项目,并配置 Maven 依赖。接着,在 `WEB-INF` 目录下配置 `web.xml` 文件,设置 JSF servlet。
67 0
|
5月前
|
JavaScript UED 前端开发
JSF 富文本编辑器横空出世,如魔法神器开启震撼富文本输入之旅!
【8月更文挑战第31天】在现代Web应用中,用户常需输入带样式、颜色及图片等功能的富文本。为此,JSF可集成如CKEditor等富文本编辑器,提供强大输入体验。首先选择合适编辑器并下载引入库文件,使用`&lt;textarea&gt;`与JavaScript实例化编辑器。后台通过`value`属性获取内容。此外,还需配置编辑器选项、处理特殊字符和进行充分测试以确保稳定性和安全性,提升用户体验。
49 0
|
5月前
|
Java Spring
🔥JSF 与 Spring 强强联手:打造高效、灵活的 Web 应用新标杆!💪 你还不知道吗?
【8月更文挑战第31天】JavaServer Faces(JSF)与 Spring 框架是常用的 Java Web 技术。本文介绍如何整合两者,发挥各自优势,构建高效灵活的 Web 应用。首先通过 `web.xml` 和 `ContextLoaderListener` 配置 Spring 上下文,在 `applicationContext.xml` 定义 Bean。接着使用 `@Autowired` 将 Spring 管理的 Bean 注入到 JSF 管理的 Bean 中。
79 0
|
5月前
|
开发者 Java 开发框架
JSF与EJB,打造企业级应用的神器!让你的Web应用更加稳定、高效!
【8月更文挑战第31天】在现代企业级应用开发中,JSF(JavaServer Faces)与EJB(Enterprise JavaBeans)是两大核心技术。JSF作为一款基于Java的Web应用框架,以其丰富的UI组件和表单处理功能著称;EJB则专注于提供分布式事务处理及远程调用等企业级服务。两者的结合为企业应用带来了高效便捷的开发模式。下文将通过一个简单的示例展示如何利用JSF进行用户信息的输入与保存,并借助EJB实现相关业务逻辑。尽管这一组合具有明显优势,但在实际应用中还需考虑其局限性并作出合理选择。
63 0
|
5月前
|
开发者 安全 SQL
JSF安全卫士:打造铜墙铁壁,抵御Web攻击的钢铁防线!
【8月更文挑战第31天】在构建Web应用时,安全性至关重要。JavaServer Faces (JSF)作为流行的Java Web框架,需防范如XSS、CSRF及SQL注入等攻击。本文详细介绍了如何在JSF应用中实施安全措施,包括严格验证用户输入、使用安全编码实践、实施内容安全策略(CSP)及使用CSRF tokens等。通过示例代码和最佳实践,帮助开发者构建更安全的应用,保护用户数据和系统资源。
66 0
|
5月前
|
开发者 iOS开发 C#
Uno Platform 入门超详细指南:从零开始教你打造兼容 Web、Windows、iOS 和 Android 的跨平台应用,轻松掌握 XAML 与 C# 开发技巧,快速上手示例代码助你迈出第一步
【8月更文挑战第31天】Uno Platform 是一个基于 Microsoft .NET 的开源框架,支持使用 C# 和 XAML 构建跨平台应用,适用于 Web(WebAssembly)、Windows、Linux、macOS、iOS 和 Android。它允许开发者共享几乎全部的业务逻辑和 UI 代码,同时保持原生性能。选择 Uno Platform 可以统一开发体验,减少代码重复,降低开发成本。安装时需先配置好 Visual Studio 或 Visual Studio for Mac,并通过 NuGet 或官网下载工具包。
480 0
下一篇
开通oss服务