【Hybrid开发高级系列】AngularJS(三)——开发实践

1 开发实践

AngularJS体验式编程系列文章

http://blog.fens.me/series-angular/

AngularJS实战

http://www.imooc.com/learn/156

1.1 工程搭建

AngularJS从构建项目开始

http://blog.fens.me/angularjs-yeoman-project/

1.1.1 使用Yeoman自动生成工程

Yeoman官方教程:用Yeoman和AngularJS做Web应用

http://blog.jobbole.com/65399/

1.1.1.1 Yeoman安装

        在安装Yeoman之前,你需要确认以下配置:

Node.js版本在0.10以上

npm版本在1.3.7以上

        安装好Node之后,你就可以用命令行来安装Yeoman了。 注意:大部分情况下Yeoman是要通过命令行来操作的,不同的系统执行以下命令的地方不太一样:Mac下请使用终端,Linux下使用shell,Windows下使用Cygwin

$ npm install--global yo

        如果你看到了’permission errors’或者’access errors’,你需要在这条命令前面加上’sudo’。通过

$ yo  --version && bower --version && grunt --version

        命令来检查是不是所有东西都已经安装好了。在执行完上述命令后,你应该会看到有四个版本号会被打印出来:

    • Yeoman

    • Bower

    • Grunt

    • GruntCLI(Grunt的命令行界面)

        适用本教程的Yeoman, Bower和Grunt版本

    安装Yeoman生成器

        在传统的Web开发流程中,你可能会花很多时间在配置代码模板、下载依赖还有手动组件项目文件结构上。而Yeoman就是来简化这个流程的!前面说的那些繁重的工作都会被交给Yeoman来完成。让我们来试试用Yeoman来创建一个AngularJS项目吧! 用下面这行命令进入Yeoman的菜单:

$ yo

        用键盘的上下键来操作菜单,当选项’install agenerator’被高亮的时候按下回车键。 接下来我们需要寻找一个合适的生成器。搜索’angular’的话,你会得到很多搜索结果。这些生成器都是由许多Yeoman开源社区贡献的。在这个例子里,我们使用的是’generator-angular’。当选中了’generator-angular’后,按下回车执行安装,它所依赖的Node包就会开始被下载了。

        如果你知道要安装的生成器的名字,你可以直接用npm来安装:

$ npm install -g generator-angular

        下面是一张预览图:

        这个例子使用的generator-angular版本,或者你可以直接安装0.7.1这个版本:

$ npm install-g generator-angular@0.7.1

1.1.1.2 使用生成器搭建你的应用

        你可以在Yeoman的菜单中操作已经安装好的生成器:

$ yo

        等一下!不要直接就运行生成器了。重新创建一个新的项目目录,生成器会在这个目录下生成出你的项目文件的。

$ mkdir mytodo

$ cd mytodo

        执行’yo’,选中’Run the Angular generator’,运行生成器。当你比较熟悉Yo的时候,就可以不通过菜单直接运行生成器:

$ yo angular

        一些生成器也会提供一些有共同开发库(common developerlibraries)的可选配置来定制你的应用,能够加速初始化你的开发环境。 generator-angular会询问你需不需要使用Sass和/或者Bootstrap,使用’n'和’y'进行选择。

        然后你需要选择你需要使用的Angular模块。Angular模块是一些带有特定功能的独立的JS文件。举个例子,ngResource模块(angular-resource.js)提供了RESTful服务。你可以使用空格键来取消项目。下面来看一看默认值。(当你在试用空格的效果时,确保所有的模块都被标记为绿色)

        好的,现在按下回车键。Yeoman将会自动构建你的应用、拉取需要的依赖并在你的工作流中创建一些有帮助的Grunt任务(GruntTasks)。几分钟后,我们就能正式开始啦!

1.1.1.3 由Yeoman构建的文件目录结构

        打开’mytodo’目录,你会看到下面的文件结构:

app/:Web应用的父级目录。

    index.html:Angular应用的基准HTML文件(base htmlfile)

    404.html、favicon.ico和robots.txt:通用的Web文件,Yeoman已经将它创建出来了,你不需要再手动去创建


    bower_components:存放项目相关的JavaScript或Web依赖,由bower安装的

    scripts:我们的JS文件

        app.js:主程序

        controllers:Angular控制器

    styles:我们的CSS文件

    views:Angular模板

Gruntfile.js、package.json 以及node_modules:Grunt需要使用的依赖以及配置。

test和karma.conf.js/karma-e2e.conf.js:测试框架以及针对这个项目的单元测试,包括了为控制器写的样板测试(boilerplatetests)。

1.2 架构设计技巧

1.2.2 请求Service层


1.2.3 数据模型层


1.2.4 业务逻辑层


1.2.5 界面表现层


1.3 代码开发技巧

1.3.1 跨html跳转到某一个业务模块

$window.location.href = 'registerIndex.html#/userInfoInput';

var registerModule = angular.module("registerModule", ['ui.router', 'hj-User', 'hj-Message', 'ngAnimate', 'hj-Loadding']).config(function($stateProvider,$urlRouterProvider){

                        $urlRouterProvider.otherwise("mobileInput");   

                        $stateProvider.state('mobileInput',{

                                                                        url: '/mobileInput',

                                                                        templateUrl: 'registerStep1.html',

                                                                        controller: 'sendMsgCtr'

                                                            }).state('vrfMsg',{

                                                                        url: '/vrfMsg',

                                                                        templateUrl: 'registerStep2.html',

                                                                        controller: 'vrfMsgCtr'

                                                            }).state('userInfoInput', {

                                                                        url: '/userInfoInput',

                                                                        templateUrl: 'registerStep3.html',

                                                                        controller: 'userInfoInputCtr'

                                                            }).state('passwordInput',{

                                                                        url: '/passwordInput',

                                                                        templateUrl: 'registerStep4.html',

                                                                        controller: 'passwordInputCtr'

                                                            });

});


原理解析:

        其实AngularJS的页面内的内容切换,也是基于html的锚点机制来实现的,不同锚点对应显示不同html部分的内容。

1.3.2 页面回退

        下面方法不好用,不如直接用history对象操作简单:

window.history.back();

window.history.go(-1);


在angularJS中实现返回前一页

http://blog.csdn.net/qianqianyixiao1/article/details/51146519

AngularJs返回前一页面时刷新一次前面页面

http://blog.csdn.net/ywl570717586/article/details/50505536


html

<script src="lib/angular/angular-1.4.9/angular.js"></script>

<script src="lib/angular/angular-ui-router.min.js"></script>


app

   angular.module('ConsoleUIApp', ['ui.router','ui.bootstrap'])

       .config(function ($stateProvider, $urlRouterProvider, $httpProvider) {

            // For any unmatched url, redirect to /state1

           $urlRouterProvider.otherwise("/home");


           $stateProvider

               .state('home', {

                   url: "/home",

                   templateUrl: "views/home.html",

                    controller: 'HomeCtrl'

                })

               .state('testing', {

                   url: "/testing",

                   templateUrl: "views/testing.html",

                   controller: 'TestingCtrl'

                })

        })

       .run(function($rootScope, growl, $state, $stateParams) {

           $rootScope.$state = $state;

           $rootScope.$stateParams = $stateParams;

           $rootScope.$on("$stateChangeSuccess",  function(event, toState, toParams, fromState, fromParams) {

                //to be used for back button won't work when page is reloaded.

               $rootScope.previousState_name = fromState.name;

               $rootScope.previousState_params = fromParams;

            });

            //back button function called from back button's ng-click="back()"

            $rootScope.back = function() {//实现返回的函数

            $state.go($rootScope.previousState_name,$rootScope.previousState_params);

          };

        });

controller:

     $scope.sub =function(addRode) {

     $rootScope.back()//直接使用

     }


https://github.com/angular-ui/ui-router/issues/92

1.3.3 路由变化监控

AngularJS中locationchange、routechange事件

http://blog.csdn.net/spy19881201/article/details/17096675

[javascript]AngularJS-需要$routeChangeStart和$locationChangeStart的一些组合

http://www.itstrike.cn/Question/f341de90-c2ae-4d71-b0e6-c547c92fb4bf.html

1.3.4 路由拦截与重定向

        路由拦截的原理在于监听$stateChangeStart或者$locationChangeStart事件,在此事件中对即将跳转的路由状态进行拦截解析并做重定向处理。

//    function(event, toState, toParams, fromState, fromParams)

    $rootScope.$on('$stateChangeStart', function(event){

        var toState = arguments[1];

        var toParams = arguments[2];

        var fromState = arguments[3];

        var fromParams = arguments[4];

        if(toState.name =="myIndexNoOn"){

            if(hj.UserUtil.checkLoginStatus())

            {

                $state.go("infoIndexOn");

            }

        }

        else{

            //This will load the current route first (ie: '/home'), and then

            //redirect the user to the correct 'login' route.

        }

    });

1.3.5 页面Loading生命周期事件

    View Load Events视图加载事件

    $viewContentLoading- 当视图开始加载,DOM渲染完成之前触发,该事件将在$scope链上广播此事件。

$scope.$on('$viewContentLoading',function(event, viewConfig){

    // Access to all the view config properties.

    // and one special property 'targetView'

    // viewConfig.targetView 

});

    • $viewContentLoaded-当视图加载完成,DOM渲染完成之后触发,视图所在的$scope发出该事件。

$scope.$on('$viewContentLoaded',function(event){ ... });

$scope.$watch('$viewContentLoaded',function(event){ ... });

1.3.6 依赖注入的顺序与方法参数的引用属性必须保持一致

        如上图就是错误写法,这样会导致构造方法入参类型是错的!!!

    原因分析:

        AngularJS中注入依赖,本质上也是根据类名去寻找对应类的代码逻辑地址,如果有多个对象注入,在初始化方法中,必须是按照注入顺序传递进来,因为JS是无类型的,切记切记。

1.3.7 Service的Factory声明方式使用

AngularJS中service,factory,provider的区别

http://my.oschina.net/tanweijie/blog/295067

简介AngularJS中使用factory和service的方法

http://www.xker.com/page/e2015/06/199141.html

使用Factory创建复制数据对象单例:

assetIndex.factory("assetData", function($rootScope, hjFundService) {

   var assetObj = {

        totalAsset : '----',

        yestodayProfit : '----',

        totalProfit : '----',

        zqAsset : '----',

        fundAsset : '----',

        highAsset : '----',

        mpData : {},

        mpSize : 0,

        mpIndexUrl : '../account/mpIndex.html'

    };


    assetObj.reloadAssetData = function(callback, callbackError){

        //数值在页面失去焦点后被释放了,在此重新获取一次,保险一点

        var hjUserId = hj.UserUtil.getCmfUserId();

        if(!hjUserId) return;


        var promise = hjFundService.queryTotalAsset({

            userId: hjUserId

        });

        promise.then(function(data) {

            assetObj.totalAsset = data.totalAsset;

        }, function(e) {

            assetObj.totalAsset = '----';

        });

        ……


        promise = hjFundService.queryMyMpList({

            userId: hjUserId

        });

        promise.then(function(data) {

            assetObj.mpData = data;

            assetObj.mpSize =data.mpList.length;

            assetObj.mpIndexUrl ='../account/mpIndex.html';


            if(callback)

            {

                callback();

            }

        }, function(e) {

            assetObj.mpSize = 0;

            if(callbackError)

            {

                callbackError();

            }

        });

    };

    return assetObj;

});

1.3.8 图片轮播代码

1.3.9 控件查询

var scrollObj = document.querySelector('.fundVoteLists');

1.3.10 登录退转后,回退到页面,页面事件响应失效问题

    问题:

        从购买页面做重定向到登录页,再从登录页登录成功回到购买页面,购买页面的事件响应失效。

    原因分析:

        在controller加载时,碰到登录失效时,虽然要跳转到登录页,但是当前runloop周期内,还是应该继续执行剩余代码,因为事件绑定逻辑都要执行完,不然页面回退回来,就会发现事件无法响应。

2 参考链接

2.1 AngularJS基础

整理AngularJS中的一些常用指令

http://www.xker.com/page/e2015/06/198575.html


AngularJS移动开发中的坑汇总

http://blog.csdn.net/offbye/article/details/38490821?utm_source=tuicool&utm_medium=referral


25个超有用的AngularJS Web开发工具

http://www.chinaz.com/web/2015/0703/419434.shtml


AngularJS最理想开发工具WebStorm

http://blog.fens.me/angularjs-webstorm-ide/


angular通过$http与服务器通信

http://blog.csdn.net/yangnianbing110/article/details/43124679


AngularJS-常用服务

http://www.2cto.com/kf/201504/388774.html


第九讲 Angularjs常用服务$http $location $cacheFactory $log $res服务

http://www.phonegap100.com/article-416-1.html


简介AngularJS中$http服务的用法

http://www.jb51.net/article/79243.htm


AngularJS中使用路由和$location切换视图

http://www.thinksaas.cn/group/topic/348590/


angularjs通过锚链接实现页面切换的问题

https://segmentfault.com/q/1010000002949626


走进AngularJs(二)ng模板中常用指令的使用方式-吕大豹

http://www.tuicool.com/articles/jIV7rm


React vs Angular 2:战争继续

http://ouvens.github.io/article-translation/2016/04/07/react-vs-angular2-fight-rages-on.html?utm_source=tuicool&utm_medium=referral


急急急!高手请帮忙!angule js中ng-view中使用了ng-include,如何实现ng-include的这个页面刷新,外部的ng-view不刷新

http://www.oschina.net/question/2356458_233962


ng-include用法分析以及多标签页面的简单实现方式

http://my.oschina.net/keysITer/blog/630621?p=1


深入理解ng里的scope

http://get.ftqq.com/462.get


angularJs前端的页面分解与组装

http://hudeyong926.iteye.com/blog/2111664


2.2 Angular route

AngularJS -路由入门

http://www.linuxidc.com/Linux/2015-02/113532.htm


[javascript] AngularJS-需要$routeChangeStart和$locationChangeStart的一些组合

http://www.itstrike.cn/Question/f341de90-c2ae-4d71-b0e6-c547c92fb4bf.html


AngularJs ng-route路由详解

http://www.w2bc.com/article/95434


AngularJS ui-router (嵌套路由)

http://www.open-open.com/lib/view/open1416878937309.html


AngularJS使用UI Router实现表单向导

http://www.oschina.net/translate/angularjs-multi-step-form-using-ui-router


Angular监听路由变化事件

http://my.oschina.net/jack088/blog/479466


http://stackoverflow.com/questions/23585065/angularjs-ui-router-change-url-without-reloading-state

http://stackoverflow.com/questions/21309366/angularjs-ui-router-state-go-only-changing-url-in-address-bar-but-not-loa


AngularJS中locationchange、routechange事件

http://blog.csdn.net/spy19881201/article/details/17096675


2.3 Data binding

AngularJs双向绑定机制解析

http://www.2cto.com/kf/201408/327594.html


双向数据绑定---AngularJS的基本原理学习

http://www.tuicool.com/articles/vENni2Y


解析angularjs中的三种数据绑定策略

http://www.2cto.com/kf/201504/391807.html


七步从Angular.JS菜鸟到专家(3):数据绑定和AJAX

http://blog.jobbole.com/48780/


双向数据绑定---AngularJS的基本原理学习

http://www.tuicool.com/articles/vENni2Y


AngularJS中数据双向绑定(two-way data-binding)

http://www.cnblogs.com/Leo_wl/p/3715030.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容