当前位置: 首页 > 编程日记 > 正文

AngularJs学习笔记--Forms

控件(input、select、textarea)是用户输入数据的一种方式。Form(表单)是这些控件的集合,目的是将相关的控件进行分组。

表单和控件提供了验证服务,所以用户可以收到无效输入的提示。这提供了更好的用户体验,因为用户可以立即获取到反馈,知道如何修正错误。请记住,虽然客户端验证在提供良好的用户体验中扮演重要的角色,但是它可以很简单地被绕过,因此,客户端验证是不可信的。服务端验证对于一个安全的应用来说仍然是必要的。

一、Simple form

理解双向数据绑定的关键directive是ngModel。ngModel提供了从model到view和view到model的双向数据绑定。并且,它还向其他directive提供API,增强它们的行为。

复制代码
<!DOCTYPE HTML>
<html lang="zh-cn" ng-app="SimpleForm">
<head><meta charset="UTF-8"><title>PropertyEvaluation</title><style type="text/css">.ng-cloak {display: none;}</style>
</head>
<body>
<div ng-controller="MyCtrl" class="ng-cloak"><form novalidate>名字: <input ng-model="user.name" type="text"><br/>Email: <input ng-model="user.email" type="email"><br/>性别: <input value="男" ng-model="user.gender" type="radio">男<input value="女" ng-model="user.gender" type="radio">女<br/><button ng-click="reset()">还原上次保存</button><button ng-click="update(user)">保存</button></form><pre>form = {{user | json}}</pre><pre>saved = {{saved | json}}</pre>
</div>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">var app = angular.module("SimpleForm", []);app.controller("MyCtrl", function ($scope,$window) {$scope.saved = {};$scope.update = function(user) {$scope.saved = angular.copy(user);};$scope.reset = function() {$scope.user = angular.copy($scope.saved);};$scope.reset();//不合法的值将不会进入user});
</script>
</body>
</html>
复制代码

二、Using CSS classes

为了让form以及控件、ngModel富有样式,可以增加以下class:

  • ng-valid
  • ng-invalid
  • ng-pristine(从未输入过)
  • ng-dirty(输入过)

下面的例子,使用CSS去显示每个表单控件的有效性。例子中,user.name和user.email都是必填的,但当它们修改过之后(dirty),背景将呈现红色。这确保用户不会直到与表单交互之后(提交之后?),发现未能满足其有效性,才为一个错误而分心。

复制代码
<!DOCTYPE HTML>
<html lang="zh-cn" ng-app="CSSClasses">
<head><meta charset="UTF-8"><title>CSSClasses</title><style type="text/css">.ng-cloak {display: none;}.css-form input.ng-invalid.ng-dirty {background-color: #fa787e;}.css-form input.ng-valid.ng-dirty {background-color: #78fa89;}</style>
</head>
<body>
<div ng-controller="MyCtrl" class="ng-cloak"><form novalidate class="css-form" name="formName">名字: <input ng-model="user.name" type="text" required><br/>Email: <input ng-model="user.email" type="email" required><br/>性别: <input value="男" ng-model="user.gender" type="radio">男<input value="女" ng-model="user.gender" type="radio">女<br/><button ng-click="reset()">RESET</button><button ng-click="update(user)">SAVE</button></form><pre>form = {{user | json}}</pre><pre>saved = {{saved | json}}</pre>
</div>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">var app = angular.module("CSSClasses", []);app.controller("MyCtrl", function ($scope,$window) {$scope.saved = {};$scope.update = function(user) {$scope.saved = angular.copy(user);};$scope.reset = function() {$scope.user = angular.copy($scope.saved);};$scope.reset();//不合法的值将不会进入user});
</script>
</body>
</html>
复制代码

三、Binding to form and control state

在angular中,表单是FormController的一个实例。表单实例可以随意地使用name属性暴露到scope中(这里没看懂,scope里面没有一个跟form的name属性一直的property,但由于有“document.表单名”这种方式,所以还是可以获取到的)。相似地,控件是NgModelController的实例。控件实例可以相似地使用name属性暴露在form中。这说明form和控件(control)两者的内部属性对于使用标准绑定实体(standard binding primitives)绑定在视图中的这个做法是可行的。

这允许我们通过以下特性来扩展上面的例子:

  • RESET按钮仅仅在form发生改变之后才可用。
  • SAVE按钮仅仅在form发生改变而且输入有效的情况下可用。
  • 为user.email和user.agree定制错误信息。
复制代码
<!DOCTYPE HTML>
<html lang="zh-cn" ng-app="ControlState">
<head><meta charset="UTF-8"><title>ControlState</title><style type="text/css">.ng-cloak {display: none;}.css-form input.ng-invalid.ng-dirty {background-color: #fa787e;}.css-form input.ng-valid.ng-dirty {background-color: #78fa89;}</style>
</head>
<body>
<div ng-controller="MyCtrl" class="ng-cloak"><form novalidate class="css-form" name="formName">名字: <input ng-model="user.name" name="userName" type="text" required><br/><div ng-show="formName.userName.$dirty&&formName.userName.$invalid"><span>请填写名字</span></div>Email: <input ng-model="user.email" name="userEmail" type="email" required><br/><div ng-show="formName.userEmail.$dirty && formName.userEmail.$invalid">提示:<span ng-show="formName.userEmail.$error.required">请填写Email</span><span ng-show="formName.userEmail.$error.email">这不是一个有效的Email</span></div>性别: <input value="男" ng-model="user.gender" type="radio">男<input value="女" ng-model="user.gender" type="radio">女<br/><input type="checkbox" ng-model="user.agree" name="userAgree" required/>我同意:<input type="text" ng-show="user.agree" ng-model="user.agreeSign" required/><br/><div ng-show="!formName.userAgree || !user.agreeSign">请同意并签名~</div><button ng-click="reset()" ng-disabled="isUnchanged(user)">RESET</button><button ng-click="update(user)" ng-disabled="formName.$invalid || isUnchanged(user)">SAVE</button></form><pre>form = {{user | json}}</pre><pre>saved = {{saved | json}}</pre>
</div>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">var app = angular.module("ControlState", []);app.controller("MyCtrl", function ($scope,$window) {$scope.saved = {};$scope.update = function(user) {$scope.saved = angular.copy(user);};$scope.reset = function() {$scope.user = angular.copy($scope.saved);};$scope.isUnchanged = function(user) {return angular.equals(user, $scope.saved);};$scope.reset();//不合法的值将不会进入user});
</script>
</body>
</html>
复制代码

四、Custom Validation

angular为大多数公共的HTML表单域(input,text,number,url,email,radio,checkbox)类型提供了实现,也有一些为了表单验证的directive(required,pattern,,inlength,maxlength,min,max)。

可以通过定义增加定制验证函数到ngModel controller(这里是连在一起的ngModelController吗?)中的directive来定义我们自己的验证插件。为了得到一个controller,directive如下面的例子那样指定了依赖(directive定义对象中的require属性)。

  • Model到View更新 - 无论什么时候Model发生改变,所有在ngModelController.$formatters(当model发生改变时触发数据有效性验证和格式化转换)数组中的function将排队执行,所以在这里的每一个function都有机会去格式化model的值,并且通过NgModelController.$setValidity(http://code.angularjs.org/1.0.2/docs/api/ng.directive:ngModel.NgModelController#$setValidity)修改控件的验证状态。
  • View到Model更新 - 一个相似的方式,无论任何时候,用户与一个控件发生交互,将会触发NgModelController.$setViewValue。这时候轮到执行NgModelController$parsers(当控件从DOM中取得值之后,将会执行这个数组中所有的方法,对值进行审查过滤或转换,也进行验证)数组中的所有方法。

在下面的例子中我们将创建两个directive。

  • 第一个是integer,它负责验证输入到底是不是一个有效的整数。例如1.23是一个非法的值,因为它包含小数部分。注意,我们通过在数组头部插入(unshift)来代替在尾部插入(push),这因为我们想它首先执行并使用这个控件的值(估计这个Array是当作队列来使用的),我们需要在转换发生之前执行验证函数。
  • 第二个directive是smart-float。他将”1.2”和”1,2”转换为一个合法的浮点数”1.2”。注意,我们在这不可以使用HTML5的input类型”number”,因为浏览器不允许用户输入我们预期的非法字符,如”1,2”(它只认识”1.2”)。
复制代码
<!DOCTYPE HTML>
<html lang="zh-cn" ng-app="CustomValidation">
<head><meta charset="UTF-8"><title>CustomValidation</title><style type="text/css">.ng-cloak {display: none;}.css-form input.ng-invalid.ng-dirty {background-color: #fa787e;}.css-form input.ng-valid.ng-dirty {background-color: #78fa89;}</style>
</head>
<body>
<div class="ng-cloak"><form novalidate class="css-form" name="formName"><div>大小(整数 0 - 10):<input integer type="number" ng-model="size" name="size" min="0" max="10"/>{{size}}<br/><span ng-show="formName.size.$error.integer">这不是一个有效的整数</span><span ng-show="formName.size.$error.min || formName.size.$error.max">数值必须在0到10之间</span></div><div>长度(浮点数):<input type="text" ng-model="length" name="length" smart-float/>{{length}}<br/><span ng-show="formName.length.0error.float">这不是一个有效的浮点数</span></div></form>
</div>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">var app = angular.module("CustomValidation", []);var INTEGER_REGEXP = /^\-?\d*$/;app.directive("integer", function () {return {require:"ngModel",//NgModelControllerlink:function(scope,ele,attrs,ctrl) {ctrl.$parsers.unshift(function (viewValue) {//$parsers,View到Model的更新if(INTEGER_REGEXP.test(viewValue)) {//合格放心肉ctrl.$setValidity("integer", true);return viewValue;}else {//私宰肉……ctrl.$setValidity("integer", false);return undefined;}});}};});var FLOAT_REGEXP = /^\-?\d+(?:[.,]\d+)?$/;app.directive("smartFloat", function () {return {require:"ngModel",link:function(scope,ele,attrs,ctrl) {ctrl.$parsers.unshift(function(viewValue) {if(FLOAT_REGEXP.test(viewValue)) {ctrl.$setValidity("float", true);return parseFloat(viewValue.replace(",", "."));}else {ctrl.$setValidity("float", false);return undefined;}});}}});
</script>
</body>
</html>
复制代码

五、Implementing custom form control (using ngModel)

angular实现了所有HTML的基础控件(input,select,textarea),能胜任大多数场景。然而,如果我们需要更加灵活,我们可以通过编写一个directive来实现自定义表单控件的目的。

为了制定控件和ngModel一起工作,并且实现双向数据绑定,它需要:

  • 实现render方法,是负责在执行完并通过所有NgModelController.$formatters方法后,呈现数据的方法。
  • 调用$setViewValue方法,无论任何时候用户与控件发生交互,model需要进行响应的更新。这通常在DOM事件监听器里实现。

可以查看$compileProvider.directive(http://www.cnblogs.com/lcllao/archive/2012/09/09/2677190.html)获取更多信息。

下面的例子展示如何添加双向数据绑定特性到可以编辑的元素中。

复制代码
<!DOCTYPE HTML>
<html lang="zh-cn" ng-app="CustomControl">
<head><meta charset="UTF-8"><title>CustomControl</title><style type="text/css">.ng-cloak {display: none;}div[contenteditable] {cursor: pointer;background-color: #D0D0D0;}</style>
</head>
<body ng-controller="MyCtrl">
<div class="ng-cloak"><div contenteditable="true" ng-model="content" title="点击后编辑">My Little Dada</div><pre>model = {{content}}</pre><button ng-click="reset()">reset model tirgger model to view($render)</button>
</div>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">var app = angular.module("CustomControl", []);app.controller("MyCtrl", function ($scope) {$scope.reset = function() {$scope.content = "My Little Dada";//在这里如何获取NgModelController呢?如果你们知道,希望可以指点指点!谢谢};});app.directive("contenteditable", function () {return {require:"ngModel",link:function (scope, ele, attrs, ctrl) {//view -> modelele.bind("blur keyup",function() {scope.$apply(function() {console.log("setViewValue");ctrl.$setViewValue(ele.text());});});//model -> viewctrl.$render = function(value) {console.log("render");ele.html(value);};//读取初始值ctrl.$setViewValue(ele.text());}};});
</script>
</body>
</html>
复制代码

转载于:https://www.cnblogs.com/heidsoft/p/3977255.html

相关文章:

天秤座的爱情(转)

若不是秤子们爱上了爱情&#xff0c;或许&#xff0c;也就不用独自承受那么多。他们的爱情就像在上演的一部电影&#xff0c;他们就在这出戏里&#xff0c;眼看着它从开始到结束。落幕并不可怕&#xff0c;秤子们在乎的是他们成就了一部电影。 秤子们不喜欢落入俗套中的爱情。与…

虚幻引擎C++终极射手教程 Unreal Engine C++ The Ultimate Shooter Course

虚幻引擎C终极射手教程 Unreal Engine C The Ultimate Shooter Course MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |时长:55节课(8小时53分钟)|大小…

Nio得知3——该示范基地:多路复用器模式

Reactor模式和NIO 本文可以看作是Doug Lea Scalable IO in Java一文的翻译。当前分布式计算 Web Services盛行天下&#xff0c;这些网络服务的底层都离不开对socket的操作。他们都有一个共同的结构&#xff1a; 1. Read request 2. Decode request 3. Process service 4. Enco…

c语言随机数生成0 99函数,C语言生成随机数的函数、延时函数

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼下面C语言代码使用了生成随机数的函数、延时函数。请大家仔细观察其显示效果。从以下代码&#xff0c;我们可以得出一个重要的结论&#xff1a;当上述两类函数被放入循环时&#xff0c;应作出一定修改。同时还应关注其参数的定义位…

2022-2028年中国乙酸钴行业发展现状调研及市场前景规划报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国乙酸钴行业市场行业相关概述、中国乙酸钴行业市场行业运行环境、分析了中国乙酸钴行业市场…

MS UI Automation Introduction

MS UI Automation Introduction 2014-09-17 MS UI Automation是什么 UIA架构 UI自动化模型 UI自动化树概述 UI自动化控件模式概述 UI 自动化属性概述 UI 自动化事件概述 示例 使用UISpy工具 UI自动化提供者 常见问题分析解决 控件无法识别 Timing issue 本地化问题 自动化技术和…

spring+mybatis事务的readonly属性无效

在Spring配置事务中设置的read-only"true"不起作用&#xff0c;仍可以执行写操作&#xff1b;但是其他的正常。查看了一下DataSourceTransactionManager这个类的doBegin方法中没有判断read-only。HibernateTransactionManager.doBegain方法中则有一判断 if(!definiti…

ue5新手零基础学习教程 Unreal Engine 5 Beginner Tutorial - UE5 Starter Course

ue5新手零基础学习教程 Unreal Engine 5 Beginner Tutorial - UE5 Starter Course! 教程大小解压后&#xff1a;4.96G 语言&#xff1a;英语中英文字幕&#xff08;机译&#xff09;时长&#xff1a;4小时56分 1920X1080 mp4 虚幻引擎5新手教程&#xff01;在这个教程中&…

C语言科学计算器思路,大神教你如何用C语言实现科学计算器

i;*leni;return temp;}/*功能&#xff1a;翻译操作数* 如果运算符非法&#xff0c;则返回0&#xff0c;合法则返回非零标志*/int translateopt(char *p,int *len){char fu[NUM_OPT][LEN_OPT]{"","-","*","/","^","(&qu…

BZOJ4292 : [PA2015]Równanie

注意到f(n)不会超过1459&#xff0c;于是暴力枚举f(n)&#xff0c;检验nk*f(n)是否合法即可。 #include<cstdio> long long k,a,b,t;int i,j,ans; int main(){scanf("%lld%lld%lld",&k,&a,&b);for(i1;i<1459&&k<b/i;i){tk*i;if(a<…

Docker入门六部曲——Stack

原文链接&#xff1a;http://www.dubby.cn/detail.html?id8739 准备知识 安装Docker&#xff08;版本最低1.13&#xff09;。阅读完Docker入门六部曲——Swarm&#xff0c;并且完成其中介绍的内容。拷贝一份docker-compose.yml。确保你的虚拟机都是可用的&#xff0c;使用do…

SVD神秘值分解

SVD分解 SVD分解是LSA的数学基础&#xff0c;本文是我的LSA学习笔记的一部分&#xff0c;之所以单独拿出来&#xff0c;是由于SVD能够说是LSA的基础&#xff0c;要理解LSA必须了解SVD&#xff0c;因此将LSA笔记的SVD一节单独作为一篇文章。本节讨论SVD分解相关数学问题&#xf…

ebook download websites (to be continue...)

http://free-ebook-collection.blogspot.com/转载于:https://www.cnblogs.com/jerryhong/archive/2008/10/24/1318469.html

Blender模块化建筑环境地形场景制作视频教程 Creating modular environments

Blender模块化建筑环境地形场景制作视频教程 Creating modular environments Blender模块化建筑环境地形场景制作视频教程 Creating modular environments 流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz 语言&#xff1a;英语中英文字幕&…

文件系统演示C语言,基于C语言的简单文件系统的实现

1 题目介绍通过具体的文件存储空间的管理、文件物理结构、目录结构和文件操作的实现&#xff0c;加深对文件系统内部的数据结构、功能以及实现过程的理解。在内存中开辟一个虚拟磁盘空间作为文件存储分区&#xff0c;在其上实现一个简单的基于多级目录的单用户单任务系统中的文…

深度学习 vs 机器学习 vs 模式识别

http://www.csdn.net/article/2015-03-24/2824301 【编者按】本文来自CMU的博士&#xff0c;MIT的博士后&#xff0c;vision.ai的联合创始人Tomasz Malisiewicz的个人博客文章&#xff0c;阅读本文&#xff0c;你可以更好的理解计算机视觉是怎么一回事&#xff0c;同时对机器学…

2022-2028年中国乙丙橡胶行业市场全景调查及投资潜力研究报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国乙丙橡胶行业市场行业相关概述、中国乙丙橡胶行业市场行业运行环境、分析了中国乙丙橡胶行…

ubuntu 下利用ndiswrapper安装无线网卡驱动

本文转载自 http://kangxincai.is-programmer.com/posts/10488.html 首先 安装 ndiswrapperubuntu下也就是 ndisgtk (用于安装无线网卡驱动)sudo apt-get install ndisgtk安装好了之后&#xff0c;找到你的无线网卡在windows下的驱动文件(含有.inf的目录)&#xff08;可以从网…

TSP问题——动态规划

Traveling Salesman Problem Description&#xff1a; Time Limit: 4sec Memory Limit:256MB 有编号1到N的N个城市&#xff0c;问从1号城市出发&#xff0c;遍历完所有的城市并最后停留在N号城市的最短路径长度。 Input&#xff1a;…

Blender从头到尾创建一辆宝马轿车视频教程

Blender从头到尾创建一辆宝马轿车视频教程 Blender: Create Realistic BMW 507 From Start to Finish 流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09;|大…

OC学习笔记之Foundation框架NSNumber、NSValue和NSDate(转)

一、NSNumber OC数组类NSArray&#xff0c;它只能存放 OC的对象&#xff0c;对于基本的数据类型确无能为力&#xff0c;但是实际编程中经常要把基本的数据如int、float&#xff0c;结构体存放的OC数组中&#xff0c;怎么办&#xff1f;这里的 NSNumber就有用了&#xff0c;它能…

android读取xml 字符串,Android 读取本地Xml文件,并转换成String

问题不是解析本地 xml 文件&#xff0c;而是要将 xml 文件中的所有内容(包含格式&#xff0c;标签等)&#xff0c;直接转换成 String。与前端H5页面交互时&#xff0c; iOS 在请求远程 xml 文件耗时太长(有时需要4~5s)&#xff0c;所以采用本地下载&#xff0c;然后传给前端的方…

Docker入门六部曲——容器

原文链接&#xff1a;http://www.dubby.cn/detail.html?id8734 准备 已经安装好Docker 1.13或者以上的版本。读完的上一篇文章&#xff08;基本引导&#xff09;。简单的测试一下你的本地环境是否已经OK了&#xff1a;docker run hello-world。 介绍 让我们开始构建一个Doc…

window.name实现的跨域数据传输

2019独角兽企业重金招聘Python工程师标准>>> 这篇文章是对 JavaScript跨域总结与解决办法 的补充。 有三个页面&#xff1a; a.com/app.html&#xff1a;应用页面。a.com/proxy.html&#xff1a;代理文件&#xff0c;一般是一个没有任何内容的html文件&#xff0c;需…

ajax frameworks(转贴)

Thinking in AJAX(三) —— AJAX框架汇总 引 此文原出于AJAX Patterns网站的一篇《Ajax Frameworks》的wiki文章&#xff0c;很早前我就注意到&#xff0c;后来在国内也有人翻译了&#xff0c;不过最近发现此wiki还是在不断添加维护中&#xff0c;截止此文发布前&#xff0c;作…

Maya角色面部表情动画制作视频教程 Maya: Facial Rigging

Maya角色面部表情动画制作视频教程 Maya: Facial Rigging Maya角色面部表情动画制作视频教程 Maya: Facial Rigging Maya角色面部表情动画制作视频教程 Maya: Facial Rigging MP4 |视频:h264&#xff0c;1280x720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 语言&#x…

(一三〇)UITextField的光标操作扩展

简介 在iOS开发中&#xff0c;有时候需要完全自主的定义键盘&#xff0c;用于完整的单词输入&#xff0c;例如计算机应用中&#xff0c;需要一次性的输入sin(&#xff0c;在移动光标时要完整的跳过sin(&#xff0c;在删除时也要完整的删除&#xff0c;这就需要对光标的位置进行…

android 多个占位符,Android多语言支持:由于占位符计数不同导致的字符串格式问题...

我正在制作一个法语Android应用程序,我正在努力支持英语.我使用“占位符”来格式化我的字符串,因此我可以将它们调整为男性和女性用户.例如,我的s​​trings.xml文件中的这个字符串&#xff1a;Les %1$s sont compliqu%2$ss...将成为“Les hommessontcompliqus”(“男人很复杂”…

Docker入门六部曲——Swarm

原文链接&#xff1a;http://www.dubby.cn/detail.html?id8738 准备工作 安装Docker&#xff08;版本最低1.13&#xff09;。安装好Docker Compose&#xff0c;上一篇文章介绍过的。安装好Docker Machine&#xff0c;上一篇文章也提到了&#xff0c;Mac和Windows已经预先安装…

Ubuntu 查看磁盘空间大小命令转

df -hDf命令是linux系统以磁盘分区为单位查看文件系统&#xff0c;可以加上参数查看磁盘剩余空间信息&#xff0c;命令格式&#xff1a;df -hl显示格式为&#xff1a; 文件系统 容量 已用 可用 已用% 挂载点 Filesystem Size Used Avail Use% Moun…