使用 AngularJS 从零构建大型应用

2024-06-24 06:08

本文主要是介绍使用 AngularJS 从零构建大型应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 0、导言
  • 1、准备工作
  • 2、构建框架
  • 3、丰富你的directives
  • 4、公用的services
  • 5、用controllers组织业务

导言

纵览线上各种AngularJS教程,大部分都是基础与一些技巧分析。
如果你已经能运行你的ng-app,但又找不到实际案例可以参考。那么本文应该对您有所帮助。
本文将以电商产品:友好速搭 其中的 店铺后台 作为的实际案例,裸奔展示如何从零构建“自以为大型的”AngularJS应用。
应用基于AngularJS 1.2.24版本。

准备工作

1、我们使用了以类型优先的目录结构。
├── js
│   ├── app.js
│   ├── directives.js
│   ├── services.js
│   ├── controllers
│   │   ├── BaseController.js // controller基类
│   │   ├── Customer.js // 顾客管理
│   │   ├── Product.js // 商品管理
│   │   ├── Order.js // 订单管理
│   │   ├── Domain.js // 域名管理
│   │   ├── Payment.js // 收款方式
│   │   └── ... // 其他各种controller
│   ├── directives
│   │   ├── ysBtn.js // 按钮组件
│   │   ├── ysCalendar.js // 日历组件
│   │   ├── ysImgeditor.js // 图片编辑器
│   │   ├── ysPopWindow.js // 模态弹窗组件
│   │   └── ... // 其他各种组件
│   └── services
│   │   ├── Graphic.js // 图片文件处理service
│   │   ├── Popup.js // 弹层service
│   │   ├── Uri.js // 与Uri相关操作service ($http等ajax操作封装于此)
│   │  └── ... // 其他各种service
│   ├── config
│   │   ├── Navigation.js // 主导航配置
│   │   ├── Route.js // 路由配置
│   │   ├── RouteProvider.js // 配置$routeProvider
│   │   ├── OnRootScope.js // 为$rootScope配置$onRootScope方法
│   │   ├── SceDelegate.js // 配置$sceDelegateProvider
│   │   ├── Uri.js // 后端服务API配置
│   │   └── ... // 其他各种config
├── lib
│   ├── bower_components
│   │   ├── angular
│   │   │   ├── angular.min.js
│   │   │   └── ...
│   │   ├── angular-route
│   │   ├── angular-sanitize
│   │   ├── angular-route
│   │   └── ... // 其他bower管理的lib
│   ├── URI.min.js
│   ├── class.js
│   └── ... // 其他手动管理的lib
├── img
├── css
└── html // controllers对应的views的模板

2、使用less作为css的预处理器。
3、使用bower管理依赖的JS库。
4、使用grunt作为项目打包工具。
5、使用fiddler4作为http请求调试工具。
6、为了可以使用庞大的jquery插件库,我们也引入了jquery。
7、controllers、directives、services 等部分的设计参考自: http://trochette.github.io/Angular-Design-Patterns-Best-Practices/

准备了半天,访问如下的index页面,angular 的应用是时候跑起来了。
应用代码展示

一个实际的案例看起来总是要比教程复杂些。下面是项目启动后友好速搭店铺后台的概貌。
店铺后台

什么?不是说好的从零开始构建吗?怎么就跑起来了?
好吧,请把上面这个预览图当做设计稿。我们开始构建框架。

构建框架

根据设计,从结构上将页面划分为

顶部 <div class='fw-topbar' ng-controller='TopbarController'></div>
导航 <ys-navigation ng-controller='ysNavigationController' ng-show='initDone'></ys-navigation>
内容 <div class='fw-main-content' id='main_cnt' ng-view=''></div>
导航的点击会改变浏览器当前的url,内容区域渲染对应模块的内容。

下面开始配置angularJS,来达到上面的目标。
在 js/app.js 配置 YeeshopManager 这个 module,并将它的引用赋值到全局变量YeeshopManagerModule,方便后续继续对其进行配置。
配置module

为了方便管理众多directives与services。我们分别创建了
js/directives.js 集合所有directives的module - YeeshopManager.directives
配置directives

js/services.js 集合所有services的module - YeeshopManager.services
配置services

接下来,配置应用为不同路径的请求调用对应的 controller与模板
在 config/Route.js 中先定义好的规则
配置Route.js

在 config/RouteProvider.js 中配置 $routeProvider
配置$routeProvider

当我们使用 #/guide 路径访问友好速搭店铺后台的新手引导页面的时候,
ngview
ngRoute将为这个index文件上带有ng-view的节点渲染对应的模板 guide.html 并且运行对应的 GuideController。

结构上划分的三个区域对应的controller的关系
顶部 -> TopbarController
导航 -> ysNavigationController
内容 -> 由ngRoute动态的根据当前url和配置,加载对应模块的内容。
至此,大体的结构已经完成。

每个Controller创建的$scope都能独立很好的运行,但有时$scope之间也需要通讯。这时,我们需要为$rootScope配置一个方法,来完成这个工作。

在 config/OnRootScope.js 中配置 $rootScope
配置rootScope
使用$provide的decorator方法在$rootScope注册的时候,注入一个 $onRootScope 的方法。

需要被通知的$scope调用 $onRootScope来监听事件'notification',
发出通知的controllers, directives,或 services中,只需要注入 $rootScope 服务。就可以很方便的进行通知。
收到通知

友好速搭作为一款SAAS产品,支持商家自行绑定域名,让用户更好的记住您的域名和品牌。

angularJS构建的应用程序,需要将静态资源部署在CDN上,来保证用户访问的快速流畅。
那么,如果我绑定了 http://myshop.com/ ,店铺后台的地址就会是 http://myshop.com/admin,
这时CDN静态资源的地址会是形如 http://cdn.com/js/app.js。
当应用的host http://myshop.com/ 和引用资源的host http://cdn.com/ 不一致时,
angular会告诉你 Error: [$sce:insecurl] ,资源因安全策略而加载失败。

配置资源白名单$sceDelegateProvider.resourceUrlWhitelist,允许angular跨域请求指定的url的资源。
白名单
至此,我们完成对YeeshopManagerModule的配置。

丰富你的directives

框架构建完成了,参考第二节中的设计稿,接下来我们需要为系统添加各种UI组件。比如图标、按钮、下拉菜单、弹窗。依照angularJS创始人Misko Hevery设计的初衷:
“构建UI应该是声明式的。”
那么,我们也设计自己的规则,来声明UI组件:

图标 <ys-ico></ys-ico>
按钮 <ys-btn></ys-btn>
下拉菜单 <ys-dropdown></ys-dropdown>
弹窗 <ys-popupwindow></ys-popupwindow>
……

完成了以上的思(yi)考(yin),我们着手来声明图标组件。
声明图标组件

声明完成后,我们在模板里面进行调用。

<ys-ico type="trade"></ys-ico>

经过angularJS的编译之后输出的节点与实际效果。
图标效果

对于这个通用的自定义标签<ys-ico>,我们习惯用“组件”来称呼他。在angularJS中,称为一个directive。官方文档中的定义请越过山丘 虽然已白了头~~

使用强大的directive。我们可以将系统中需要复用的所有组件、甚至一个复用的行为全部抽象出来。当你需要使用的时候,你只是需要声明他。
例如,一个旋转的图标:

<ys-ico keepRotating type="trade"></ys-ico>

友好速搭项目早期规划的directive
展示

按照需求增加了水印编辑器directive
水印编辑器

方便商户编辑图片,增加了图片编辑器directive
图片编辑器

这时候,前端工程师的问题就来了:“还有多少directives?”
暴走
答:纵观整个项目的生命周期,所有的directive不可能在初始便全部设计并构建好。请在项目进行的过程中,按需的增加或修改、丰富你的directive,不断提升你构建view的效率。

依照上文构建与调用directive的经验。在实际项目中,我们在模块中需要10个ico,那么我们便在其模板中调用十次的<ys-ico>标签。

那么前端工程师的问题又来了:“如果模块的交互需要弹窗,难不成我要先算好有多少个?然后全部先在模块里面声明,并使用ng-show="false"全部隐藏起来?”
暴走

Don't worry.不要被 Thinking-in-AngularJs 限制了您的思维。换一个姿势 Thinking in jquery。
当我们需要一个弹窗的时候,按照往常的做法,便是在你页面架构预设好的位置(例如页面底部),插入弹窗的dom结构。
没错,弹窗还是这样实现,不同的是。我们插入的是弹窗的directive。
类似以下(简化代码未测试,仅为示例):

$('body').append($compile('<ys-popwindow data="PopupModalData">#{content}</ys-popwindow>')($scope));

我们通过动态插入directive解决了上面这个问题。但我总不能每个模块都写弹窗dom的插入吧。
这个时候,我们需要service。

公用的services

各种services为友好速搭店铺后台提供了统一的api接口调用,图像处理,弹层处理,实用工具等。
通过上面的目录,我们可以看到services文件夹下,有定义$Popup的Popup.js。
(简化代码未测试,仅为示例)
service代码

注入到您所需的模块后,愉快的调用吧!

$Popup.modal({text : '弹窗标题'});

用controllers组织业务

一切就绪,开始堆业务代码!
用controllers图片
用controllers代码

裸奔展示到此结束~有劳看官,若有任何错漏~烦请指正~

参考http://www.v2ex.com/t/168015

这篇关于使用 AngularJS 从零构建大型应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1089368

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#