AngularJS+ThinkPHP实例教程

友情提醒:内容有点多

总体思路

thinkphp通过RESTful方式提供数据给angular,前端(包括模板页面)全部由angular来接管。

示例

实现一个用户管理模块,走通增删改查4个操作,通过该示例,演示如何在thinkphp中使用angularjs。

一. 准备工作

1. 加载所需的js和css文件

angular.min.jsangular 核心库文件

angular-ui-router.min.jsangular 路由插件

angular-resource.min.js 负责与服务端restful交互的插件

layer 弹窗插件,该插件依赖于jquery-1.10.1.min.js和jquery-ui.min.js两个库文件以及一个jquery-ui.min.css样式表

bootstrap.min.cssbootstrap 核心样式表

文件结构如下:

2.引导页

准备一个angular引导页,angular通过该引导页开启一个angular应用,后续所有的操作,都是基于该引导页进行的。

友情提醒:

这里的引导页,其实就是我们应用的默认页面,具体到thinkphp中,指的就是DEFAULT_MODULE/DEFAULT_CONTROLLER/DEFAULT_ACTION对应的模板文件。第一次访问应用时,thinkphp控制器会定向到该页面,之后的模板页面,全部由angular接管,跟thinkphp的模板引擎就没有半点关系了。

3.应用首页

在引导页中通过<div ui-view="main"></div>包含我们的应用首页。便签的含义后面会有解释。

注意:这一步不是必须的,因为你也可以把应用首页的内容,全部放在引导页中,但是这样做就不够友好了。

4.搭建RESTFul环境

为了能够使用$resource,我们必须让服务端按照RESTful的方式来工作,否则,$resource就无法发挥其作用了。

thinkphp中内置了对RESTful的支持,使用方式也很简单,就是让某个Controller继承自RestController,然后按照一定的规则来编写资源方法即可。但是它有一个缺点,thinkphp内置的RESTful对资源的访问方式不够友好,其访问资源的URL结构如下:

/模块名称/控制器名称/资源名称

基于此,我们考虑使用thinkphp的路由功能,来实现对RESTful的支持,使用thinkphp的路由功能时,控制器是没有必要继承RestController的,但为了尊重tp的劳动成果,同时,为了兼顾友好的资源访问方式,最终,我使用的是RestController+路由两者结合的方式。

补充:

资源方法的命名规则为:资源名称_REST类型

REST类型有如下几种:get,post,put,delete

5. 创建数据库表

创建用户表,并初始化一些数据

DROP TABLE IF EXISTS `an_user`;
CREATE TABLE `an_user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,`user_id` int(10) unsigned NOT NULL COMMENT '用户id',`user_name` varchar(100) NOT NULL COMMENT '用户名称',`email` varchar(255) DEFAULT NULL COMMENT '邮箱地址',`tel` varchar(255) DEFAULT NULL COMMENT '手机号码',`weixin` varchar(255) DEFAULT NULL COMMENT '微信号',`qq` varchar(255) DEFAULT NULL COMMENT 'qq号码',PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户表';

INSERT INTO `an_user` VALUES ('1','1','demo1','demo1@qq.com','13100000000','weixin_test1','123456');
INSERT INTO `an_user` VALUES ('2','2','demo2','demo2@qq.com','13100000001','weixin_test2','123456');
INSERT INTO `an_user` VALUES ('3','3','demo3','demo3@qq.com','13100000002','weixin_test3','123456');
INSERT INTO `an_user` VALUES ('4','4','demo4','demo4@qq.com','13100000003','weixin_test4','123456');
INSERT INTO `an_user` VALUES ('5','5','demo5','demo5@qq.com','13100000004','weixin_test5','123456');
INSERT INTO `an_user` VALUES ('6','6','demo6','demo6@qq.com','13100000005','weixin_test6','123456');
INSERT INTO `an_user` VALUES ('7','7','demo7','demo7@qq.com','13100000006','weixin_test7','123456');
INSERT INTO `an_user` VALUES ('8','8','demo8','demo8@qq.com','13100000007','weixin_test8','123456');
INSERT INTO `an_user` VALUES ('9','9','demo9','demo9@qq.com','13100000008','weixin_test9','123456');
二. 开始吧

1. 创建引导页

前面说过,引导页其实就是我们应用的默认页面,在我的项目中,默认页面的文件路径为:

/tpl/Admin/Index/index.html

在该文件中,加入如下内容:

<!DOCTYPE html>
<html ng-app="antp">
	<head>
	    <meta charset="utf-8" />
	    <title></title>
	    <meta content="width=device-width,initial-scale=1.0" name="viewport" />
	    <meta content="" name="author" />
	    <link href="/public/css/bootstrap.min.css" rel="stylesheet" type="text/css" media="all">
	    <link href="/public/css/jquery-ui.min.css" rel="stylesheet" type="text/css" media="all">
	    <script type="text/javascript" src="/public/js/angular.min.js"></script>
	    <script type="text/javascript" src="/public/js/angular-resource.min.js"></script>
	    <script type="text/javascript" src="/public/js/angular-ui-router.min.js"></script>
	    <script type="text/javascript" src="/public/js/jquery-1.10.1.min.js"></script>
	    <script type="text/javascript" src="/public/js/jquery-ui.min.js"></script>
	    <script type="text/javascript" src="/public/js/layer/layer.js"></script>
	    <script type="text/javascript" src="/config.js"></script>
	    <script type="text/javascript" src="/app.js"></script>
		<link rel="shortcut icon" href="favicon.ico" />
	</head>
	<body>
		<div class="container-fluid">
	        <div class="row clearfix">
	            <div class="col-md-12" style="float: none;display: block;margin-left: auto;margin-right: auto;">
	                <div ui-view="main"></div>
	            </div>
	        </div>
	    </div>
	</body>
</html>

页面中加载的js和css,除了config.js和app.js,其它的在前面都已经作了说明,这两个后面也会说到。

注意html标签中的ng-app指令,该指令的内容,就是angular要开启的应用名称。

2. 开启应用

之前的index.html文件中,通过ng-app指令定义了一个应用名称,定义完之后,我们还需要开启它,开启的方式也很简单,我们需要创建一个js文件,名称为app.js,在里面先加入如下内容:

var app = angular.module("antp",["ui.router","ngResource"]);

其中,module的第二个参数,是angular的一些依赖包。

3. 配置路由

使用ui.router的路由功能,通过config预先配置好访问url、该url对应的视图模板以及控制器等信息,同样是在app.js文件中,继续加入如下内容:

app.config(function($stateProvider,$urlRouterProvider,$locationProvider) {
	//启用HTML5模式的路由,该模式下会去除URL中的#号
	//$locationProvider.html5Mode(true);
	//默认页面,所有请求不到的资源,都会转向到这个URL
    $urlRouterProvider.otherwise("/index");
    $stateProvider.state("user",{
        url: "/user",views: {
            main: {
                templateUrl: "tpl/Admin/User/index.html",controller: "UserCtroller"
            }
        }
    }).state("index",{
        url: "/index",views: {
            main: {
                templateUrl: "tpl/Admin/Index/main.html",controller: "MainCtroller"
            }
        }
    }).state("user-add",{
        url: "/user/add",views: {
            main: {
                templateUrl: "tpl/Admin/User/add.html",controller: "UserFormCtroller"
            }
        }
    }).state("user-edit",{
        url: "/user/edit/:user_id",controller: "UserFormCtroller"
            }
        }
    });
});

还记得之前引导页中的ui-view="main"吗?ui-view的名字,就是state中配置的views下面的属性名称。也许你会说,config里面配置了那么多的main,它是如何知道找的是哪个main?仔细看下代码就知道了。

注意1:控制器controller我们并没有手动写在某个页面的标签上,而是统一配置在了config里。

注意2:每个视图模板必须要对应一个控制器,并且这个控制器必须要被创建,否则,该视图将无法展示。

注意3:不要把此处的控制器和thinkphp里面的控制器搞混,事实上,他们两者之间没有任何关系。

4. 引入每个模块下的js

这里为了便于代码管理与维护,我在每个模块下面创建了一个js文件,每个模块的js完成特定的功能,这些js同样需要在app.js中被引入。

document.write('<script type="text/javascript" src="/tpl/Admin/Index/main.js"></script>');
document.write('<script type="text/javascript" src="/tpl/Admin/User/user.js"></script>');

5. 浏览器访问

在浏览器地址栏中,输入http://local.antp,将会看到如下效果:

仔细观察下地址栏,我们输入的是http://local.antp,但是却自动变成了http://local.antp/#/index,知道为什么吗?

首页,引导页中的<div ui-view="main"></div>,表示我需要路由到main这个视图,但是,我们输入的地址http://local.antp中,并没有告诉angular到底是哪个main,发生这种情况的时候,angular就会定向到默认的视图,默认的视图由$urlRouterProvider.otherwise("/index");这一句来指定。

由于/index指向的是tpl/Admin/Index/main.html,所以此处就会把main.html对应的内容展示出来。

main.html文件内容:

<div ng-include="'tpl/Admin/Public/header.html'"></div>
<blockquote>
	<p>
		我是默认页面,所有请求不到的资源,都会到我这里来...
	</p>
</blockquote>

其中,通过ng-include指令,引入了一个公共导航页面,ng-include指令中双引号内的单引号不可少内容如下:

<div style="margin-top:20px;">
	<nav class="navbar navbar-default" role="navigation">
		<div class="navbar-header">
			<a class="navbar-brand" href="#">Brand</a>
		</div>
		<div class="collapse navbar-collapse">
			<ul class="nav navbar-nav">
				<li class="active">
					 <a ui-sref="user">用户管理</a>
				</li>
			</ul>
			
		</div>
	</nav>
</div>

6. 用户列表

点击导航中的【用户管理】,即可跳转到用户列表页面,如下:


该列表对应的视图文件为tpl/Admin/User/index.html,内容如下:

<div ng-include="'tpl/Admin/Public/header.html'"></div>
<button type="button" class="btn btn-primary" ng-click="addAction()">新增</button>
<table class="table table-bordered table-striped" style="margin-top:15px;">
	<thead>
		<tr>
			<th>用户名</th>
			<th>邮箱</th>
			<th>手机号</th>
			<th>微信</th>
			<th>QQ</th>
			<th>操作</th>
		</tr>
	</thead>
	<tbody>
		<tr ng-repeat="user in data.user">
			<td>
				<a ui-sref="user-edit({user_id:user.user_id})" ng-bind="user.user_name"></a>
			</td>
			<td ng-bind="user.email"></td>
			<td ng-bind="user.tel"></td>
			<td ng-bind="user.weixin"></td>
			<td ng-bind="user.qq"></td>
			<td>
				<button type="button" class="btn btn-link">
					<a ui-sref="user-edit({user_id:user.user_id})">修改</a>
				</button>
				<button type="button" class="btn btn-link" ng-click="deleteAction(user.user_id)">删除</button>
			</td>
		</tr>
	</tbody>
</table>

为了能够从后端拿到数据,我们需要创建一个$resource资源,创建方式如下:

//通过factory创建一个service,该service通过$resource返回了一个资源对象
//$resource负责与支持restful的服务端进行数据交互
app.factory("UserService",function($resource) {
    return $resource(globalConfig.API.URL + "users/:id",{
       id: "@id"
    },{
        //query方法要求服务端返回的数据格式为数组,如果返回的是非数组格式,需要在transformResponse函数中作转换处理
    	query: {
            method: "GET",isArray: true,transformResponse: function(data) {
                return JSON.parse(data);
            }
        },update: {
            method: "PUT"
        }
    });
});

这里,创建了一个名字为UserService的资源,然后,我们还需要创建一个控制器,将UserService资源注入进去,代码如下:

//用户列表Ctroller
app.controller('UserCtroller',function($scope,$state,UserService) {
    $scope.data = {};
    //获取用户列表
    UserService.query().$promise.then(
	    function(data){
	    	//将查询结果赋值给data.user,模板中可以对data.user变量进行遍历
	    	$scope.data.user = data;
	    },function(error) {
	        console.log("An error occurred",error);
	    }
	);
    $scope.addAction = function() {
        $state.go("user-add");
    };
    $scope.deleteAction = function(user_id){
    	layer.confirm("确定要删除该用户吗",{
		  	btn: ['确定','取消']
		},function(index){
		  	layer.close(index);
		  	UserService.remove({id:user_id}).$promise.then(
	  			function(res){
	  				if(res.status){
	  					$state.go("user",null,{
	  						reload:true
	  					});
	  				}else{
	  					
	  				}
	  			},function(error) {
	  				console.log("An error occurred",error);
	  			}
		  	);
		});
    }
});

通过UserService的query方法,获取用户列表信息。

7. 新增用户

点击列表上的【新增】,将会通过$state.go("user-add");跳转到新增页面:

该页面对应的视图文件为tpl/Admin/User/add.html,内容如下:

<div ng-include="'tpl/Admin/Public/header.html'"></div>
<form class="form-horizontal" role="form" name="userForm">
	<div class="form-group">
		 <label class="col-sm-3 control-label">用户名</label>
		 <div class="col-sm-4">
		 	<input type="text" class="form-control" ng-model="user.user_name"/>
		 </div>
	</div>
	<div class="form-group">
		 <label class="col-sm-3 control-label">邮箱</label>
		 <div class="col-sm-4">
		 	<input type="email" class="form-control" ng-model="user.email"/>
		 </div>
	</div>
	<div class="form-group">
		 <label class="col-sm-3 control-label">手机号</label>
		 <div class="col-sm-4">
		 	<input type="tel" class="form-control" ng-model="user.tel"/>
		 </div>
	</div>
	<div class="form-group">
		 <label class="col-sm-3 control-label">微信号</label>
		 <div class="col-sm-4">
		 	<input type="text" class="form-control" ng-model="user.weixin"/>
		 </div>
	</div>
	<div class="form-group">
		 <label class="col-sm-3 control-label">QQ</label>
		 <div class="col-sm-4">
		 	<input type="text" class="form-control" ng-model="user.qq"/>
		 </div>
	</div>
	<div class="col-sm-offset-3 col-sm-4">
		<button type="submit" class="btn btn-primary" ng-click="submitAction(userForm)">
			保存
	    </button>
	    <button type="button" class="btn btn-default" ng-click="cancelAction()">
			返回
	    </button>
    </div>
</form>

该页面中用到了angular的ng-model指令,ng-model指令用于数据的双向绑定,注意下表单中类似于user.user_name的东西,首先,controller中会通过点号前面的user获取表单数据,表单数据就是点号后面若干个类似于user_name的对应的内容的组合。

js代码:

//新增和修改用户Ctroller
app.controller('UserFormCtroller',$stateParams,UserService) {
	if($stateParams.user_id){
		var user_id = $stateParams.user_id;
		var param = {id:user_id};
		//获取指定用户
		UserService.get(param).$promise.then(
	    	function(res) {
	            $scope.user = res;
	        },function(error) {
	            console.log("An error occurred",error);
	        }
	    );
	}
    $scope.submitAction = function(userForm) {
        if(!userForm.$valid){
        	return false;
        }
        if($stateParams.user_id){
        	//更新用户信息
        	UserService.update(param,$scope.user).$promise.then(
    			function(res) {
    				if(res.status){
    					$state.go("user");
    				}else{
    					
    				}
    			},function(error) {
    				console.log("An error occured",error);
    			}
        	);
        }else{
        	//新增
        	UserService.save($scope.user).$promise.then(
    			function(res) {
    				if(res.status){
    					$state.go("user");
    				}else{
    					
    				}
    			},error);
    			}
        	);
        }
    };
    $scope.cancelAction = function() {
    	$state.go("user");
    };
});

通过UserService的save方法来新增一个用户,而update方法则负责用户信息的修改。

注意:在修改用户的信息之前,我们需要通过UserService的get方法把用户已有的信息填充到页面上。

8. 修改用户

点击列表上的【修改】链接,进入到用户修改页面:


通过列表中的ui-sref="user-edit({user_id:user.user_id})"这一句,即可实现页面的跳转,同时,带上了user_id这个参数,可以在控制器中注入$stateParams来获取此处的参数,代码在前面已经贴过了。

9. 删除用户

点击列表上的【删除】,将会弹出一个删除确认的提示,如图:

点击【确定】后,即可通过UserService的remove方法来删除该用户。

注意:删除一个资源,也可以使用delete方法,但由于delete在有些浏览器中被当成了关键字,所以使用上需要写成UserService["delete"]这种格式。

10. thinkphp路由配置

'URL_ROUTER_ON' => true
'URL_ROUTE_RULES' => array(
		array('api/users/:id','Admin/User/user_get','',array('method'=>'get')),//注意:列表记录对应的路由必须要放在单条记录路由的后面,否则无法获取单条记录
		array('api/users',array('api/users','Admin/User/user_post',array('method'=>'post')),array('api/users/:id','Admin/User/user_put',array('method'=>'put')),'Admin/User/user_delete',array('method'=>'delete')),)

11. 后端代码

//查询用户列表或单条记录
    public function user_get(){
        $id = I('id');
        if ($id) {
        	$where = array('user_id' => $id);
        	$users = DBUtil::queryRow($this->userModel,$where);
        }else{
	        $users = DBUtil::queryList($this->userModel);
        }
        $this->response($users,'json');
    }
    
    //新增用户
    public function user_post(){
    	$user_id = DBUtil::getMaxKey($this->userModel,'user_id');
    	//angular默认post过来的数据类型为Content-Type:application/json; charset=utf-8
    	$userData = json_decode(file_get_contents('php://input'),true);
    	$userData['user_id'] = $user_id;
    	$result = DBUtil::add($this->userModel,$userData);
    	$this->response(array('status'=>$result),'json');
    }
    
    //修改用户
    public function user_put(){
    	$user_id = $_REQUEST['id'];
    	//angular默认post过来的数据类型为Content-Type:application/json; charset=utf-8
    	$userData = json_decode(file_get_contents('php://input'),true);
    	$result = DBUtil::save($this->userModel,array('user_id' => $user_id),$userData);
    	if ($result !== false) {
    		$result = true;
    	}
    	$this->response(array('status'=>$result),'json');
    }
    
    //删除用户
    public function user_delete(){
    	$user_id = $_REQUEST['id'];
    	$result = DBUtil::delete($this->userModel,array('user_id' => $user_id));
    	$this->response(array('status'=>$result),'json');
    }
三. 去除URL中的#号

默认情况下,angular通过URL中的#号来识别资源路径类别,凡是带#号的资源,统一由angular调配,而不带#号的资源,由服务端调配,如果需要去除#号,可以参考以下步骤:

1.启用html5模式

首页需要在config中注入$locationProvider,然后通过$locationProvider.html5Mode(true);来启用HTML5模式的路由。

2.加入base标签

在引导页中加入<base href="/">

3. 后端thinkphp配置

在控制器中增加一个_empty方法,在该方法中,跳转到首页。


至此,该演示示例就算完成了,如需完整代码,请访问如下网址下载即可:https://github.com/fyl123/antp,或联系QQ:2529854689

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


ANGULAR.JS:NG-SELECTANDNG-OPTIONSPS:其实看英文文档比看中文文档更容易理解,前提是你的英语基础还可以。英文文档对于知识点讲述简明扼要,通俗易懂,而有些中文文档读起来特别费力,基础差、底子薄的有可能一会就会被绕晕了,最起码英文文档中的代码与中文文档中的代码是一致的,但知识点讲述实在是差距太大。Angular.jshasapowerfuldire
AngularJS中使用Chart.js制折线图与饼图实例  Chart.js 是一个令人印象深刻的 JavaScript 图表库,建立在 HTML5 Canvas 基础上。目前,它支持6种图表类型(折线图,条形图,雷达图,饼图,柱状图和极地区域区)。而且,这是一个独立的包,不依赖第三方 JavaScript 库,小于 5KB。   其中用到的软件:   Chart.js框架,版本1.0.2,一
IE浏览器兼容性后续前言 继续尝试解决IE浏览器兼容性问题,结局方案为更换jquery、angularjs、IE的版本。 1.首先尝试更换jquery版本为1.7.2 jquery-1.9.1.js-->jquery-1.7.2.js--> jquery2.1.4.js 无效 2.尝试更换IE版本IE8 IE11-
Angular实现下拉菜单多选写这篇文章时,引用文章地址如下:http://ngmodules.org/modules/angularjs-dropdown-multiselecthttp://dotansimha.github.io/angularjs-dropdown-multiselect/#/AngularJSDropdownMultiselectThisdire
在AngularJS应用中集成科大讯飞语音输入功能前言 根据项目需求,需要在首页搜索框中添加语音输入功能,考虑到科大讯飞语音业务的强大能力,遂决定使用科大讯飞语音输入第三方服务。软件首页截图如下所示: 涉及的源代码如下所示: //语音识别$rootScope.startRecognize = function() {var speech;
Angular数据更新不及时问题探讨前言 在修复控制角标正确变化过程中,发觉前端代码组织层次出现了严重问题。传递和共享数据时自己使用的是rootScope,为此造成了全局变量空间的污染。根据《AngularJs深度剖析与最佳实践》,如果两个控制器的协作存在大量的数据共享和交互可以利用Factory等服务的“单例”特性为它们注入一个共享对象来传递数据。而自己在使用rootScope
HTML:让表单、文本框只读,不可编辑的方法有时候,我们希望表单中的文本框是只读的,让用户不能修改其中的信息,如使中国">的内容,"中国"两个字不可以修改。实现的方式归纳一下,有如下几种。方法1:onfocus=this.blur()中国"onfocus=this.blur()>方法2:readonly中国"readonly>中国"readonly="tru
在AngularJS应用中实现微信认证授权遇到的坑前言 项目开发过程中,移动端新近增加了一个功能“微信授权登录”,由于自己不是负责移动端开发的,但最后他人负责的部分未达到预期效果。不能准确实现微信授权登录。最后还得靠自己做进一步的优化工作,谁让自己是负责人呢?原来负责人就是负责最后把所有的BUG解决掉。 首先,熟悉一下微信授权部分的源代码,如下所示:
AngularJS实现二维码信息的集成思路需求 实现生成的二维码包含订单详情信息。思路获取的内容数据如下: 现在可以获取到第一级数据,第二级数据data获取不到。利用第一级数据的获取方法获取不到第二级数据。for(i in data){alert(i); //获得属性 if(typeof(data[i]) == "o
Cookie'data'possiblynotsetoroverflowedbecauseitwastoolarge(5287>4096bytes)!故事起源 项目开发过程中遇到以上问题,刚开始以为只是个警告,没太在意。后来发现直接影响到了程序的执行效果。果断寻找解决方法。问题分析 根据Chrome浏览器信息定位,显示以下代码存在错误:
AngularJS控制器controller之间如何通信angular控制器通信的方式有三种:1,利用作用域继承的方式。即子控制器继承父控制器中的内容2,基于事件的方式。即$on,$emit,$boardcast这三种方式3,服务方式。写一个服务的单例然后通过注入来使用利用作用域的继承方式由于作用域的继承是基于js的原型继承方式,所以这里分为两种情况,当作用域上面的值
AngularJS路由问题解决遇到了一个棘手的问题:点击优惠详情时总是跳转到药店详情页面中去。再加一层地址解决了,但是后来发现问题还是来了:Couldnotresolve'yhDtlMaintain/yhdetail'fromstate'yhMaintain'药店详情http://192.168.1.118:8088/lmapp/index.html#/0优惠券详情
书海拾贝之特殊的ng-src和ng-href在说明这两个指令的特殊之前,需要先了解一下ng的启动及执行过程,如下:1)浏览器加载静态HTML文件并解析为DOM;2)浏览器加载angular.js文件;3)angular监听DOMContentLoaded事件,监听到时开始启动;4)angular寻找ng-app指令,确定作用范围;
angularjs实现页面跳转并进行参数传递Angular页面传参有多种办法,我在此列举4种最常见的:1.基于ui-router的页面跳转传参(1)在AngularJS的app.js中用ui-router定义路由,比如现在有两个页面,一个页面(producers.html)放置了多个producers,点击其中一个目标,页面跳转到对应的producer页,同时将producerId
AngularJS实现表格数据的编辑,更新和删除效果实现首先,我们先建立一些数据,当然你可以从你任何地方读出你的数据var app = angular.module('plunker', ['ui.bootstrap']);app.controller('MainCtrl', function($scope) { $scope.name = 'World'; $sc
ANGULAR三宗罪之版本陷阱      坑!碰到个大坑,前面由于绑定日期时将angular版本换为angular-1.3.0-beta.1时,后来午睡后,登录系统,发现无论如何都登陆不进去了,经过调试,发现数据视图已经无法实现双向绑定了。自己还以为又碰到了“僵尸程序”了呢,对比药店端的程序发现并没有什么不同之处。后来自己经过一番思索才隐约感觉到是不是angular的版本造成的,将版本换为之前
JS实现分页操作前言 项目开发过程中,进行查询操作时有可能会检索出大量的满足条件的查询结果。在一页中显示全部查询结果会降低用户的体验感,故需要实现分页显示效果。受前面“JS实现时间选择插件”的启发,自己首先需要查看一下HTML5能否实现此效果。 整了半天,不管是用纯CSS3也好,还是用tmpagination.js还是bootstrap组件也好,到最后自己静下心来理
浏览器兼容性解决之道前言 浏览器兼容性一直是前端开发中不得不面对的一个问题。而最突出的就是IE。对绝大多数公司来说,兼容IE6的性价比已经很低,而IE7则几乎已经绝迹。所以,常见的兼容性下限是IE8。这也正是Angular1.2x的兼容性目标,Angular团队声明:Angular的持续集成服务器会在IE8下运行所有的测试。但这些测试不会运行在IE7及以下版本,它们也不会保证An
JS利用正则表达式校验手机号绪 由于项目需求,需要在前端实现手机号码的校验。当然了,对于基本的格式校验应该放在客户端进行,而不需要再将待校验的手机号发送至服务端,在服务端完成校验,然后将校验结果返回给客户端,客户端根据返回的结果再进行进一步的处理。如此反而复杂化了处理过程。 其实,处于安全考虑,应该在服务端进行二次校验。以下为在客户端的JS中校验手机号码格式
基于项目实例解析ng启动加载过程前言 在AngularJS项目开发过程中,自己将遇到的问题进行了整理。回过头来总结一下angular的启动过程。 下面以实际项目为例进行简要讲解。1.载入ng库2.等待,直到DOM树构造完毕。3.发现ng-app,自动进入启动引导阶段。4.根据ng-app名称找到相应的路由。5.加载默认地址。6.Js顺序执行,加载相应模版页sys_tpls/