细说angular Form addControl方法
在本篇博文中,我们将接触angular的验证。angular的验证是由form 指令和ngModel协调完成的。今天博主在这里想要说的是在验证在的一种特殊情况,当验证控件没有没有name属性这是不会被form捕获的。或者是你希望在ngRepeat中使用动态表达式。
下面且让我们先来从angular源码中看起如下:
首先是ngModel:
var ngModelDirective = function() {
return {
require: ['ngModel', '^?form'],
controller: NgModelController,
link: function(scope, element, attr, ctrls) {
// notify others, especially parent forms var modelCtrl = ctrls[0],
formCtrl = ctrls[1] || nullFormCtrl; formCtrl.$addControl(modelCtrl); scope.$on('$destroy', function() {
formCtrl.$removeControl(modelCtrl);
});
}
};
};
从上面我们能够看出ngModel指令会在编译时期的post link阶段会通过form的 addControl方法把自己的controller注册到父节点上的form的formController中。
在看看ngModel controller初始化代码:
var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse',
function($scope, $exceptionHandler, $attr, $element, $parse) {
....
this.$pristine = true;
this.$dirty = false;
this.$valid = true;
this.$invalid = false;
this.$name = $attr.name;
我们从上面我们可以看到 ngModel的$name属性并不支持表达式计算。
而FormController的addControl代码则是:
/**
* @ngdoc function
* @name ng.directive:form.FormController#$addControl
* @methodOf ng.directive:form.FormController
*
* @description
* Register a control with the form.
*
* Input elements using ngModelController do this automatically when they are linked.
*/
form.$addControl = function(control) {
// Breaking change - before, inputs whose name was "hasOwnProperty" were quietly ignored
// and not added to the scope. Now we throw an error.
assertNotHasOwnProperty(control.$name, 'input');
controls.push(control); if (control.$name) {
form[control.$name] = control;
}
};
从上面我们可以清楚的看见虽然ngModel注册了自己,但是这里也不一定能注册成功,ngModel心必须有自己的$name才能被注册成功。
从上面的代码中可以得出,当我们的验证失效的时候,我们可以有一个万能的方式就是 手动注册到form controller
手动注册form controller
为了我写了一个dy-name的插件,其会在post link阶段解析表达式,并把自己注册到父form controller。
如下:
.directive("dyName", [ function() {
return {
require: "ngModel",
link: function(scope, elm, iAttrs, ngModelCtr) {
ngModelCtr.$name = scope.$eval(iAttrs.dyName)
var formController = elm.controller('form') || {
$addControl: angular.noop
};
formController.$addControl(ngModelCtr); scope.$on('$destroy', function() {
formController.$removeControl(ngModelCtr);
}); }
};
}
])
使用方式:
<div ng-repeat="item in demo.fields">
<div class="control-group">
<label class="control-label"> : </label>
<div class="controls">
<input type="number" dy-name="item.field" ng-model="demo.data[item.field]" min="10" max="500" ng-required="true"/>
</div>
</div>
</div>
其实实现为在post link阶段获取到form controller,并把自己注册到form controller,而且为了消除对象的级联,将会在scope摧毁阶段remove自己。
其效果请看jsbin $addControl
注意:在formController.$addControl方法的参数传入的不是界面控件,而是ngModelController.或者名字为$addController更合适。
细说angular Form addControl方法的更多相关文章
- AngularJS form $addControl 注冊控件control
需求背景: 在form中使用编写的某component directive时.想通过form's name来对form中控件进行操作, 如使用$invalid等来ng-disabled btn. 解决 ...
- ASP.NET 中HTML和Form辅助方法
Form辅助方法 Form最重要的属性就是action和method,action指明form中的数据被提交到哪里,method指明用什么方法,默认为GET,下面是一个简单的例子: <form ...
- Django form表单功能的引用(注册,复写form.clean方法 增加 验证密码功能)
1. 在app下 新建 forms.py 定义表单内容,类型models from django import forms class RegisterForm(forms.Form): userna ...
- 让Easy UI 的DataGrid直接内嵌的JSON对象,并重写form load 方法
前言 我有这样的JSON对象 { "UserName": "jf", "UserPwd": "123456", &quo ...
- angular 封装公共方法
angular封装公共方法到service中间件,节省开发时间 layer.service.ts openAlert(callback) {// 传递回调函数 const dialogRef = th ...
- 实现同时提交多个form(基础方法) 收集
实现同时提交多个form(基础方法) 收集 分类: 1.2-JSP 1.3-J2EE 1.1J2se 1.0-Java相关2011-12-01 20:59 1644人阅读 评论(0) 收藏 举报 bu ...
- form.submit 方法 并不会触发 form.onsubmit 事件
做表单的时候发现一个奇怪的地方,总结下: form.submit 方法 并不会触发 form.onsubmit 事件,看代码: <body> <div class="con ...
- vue + elementui form resetFields方法 无法重置表单
this.$refs['form'].resetFields(); 方法无法重置.1 el-form 组件 没有添加 ref 属性 <el-form ref="form" : ...
- AngularJS的核心对象angular上的方法全面解析(AngularJS全局API)
总结一下AngularJS的核心对象angular上的方法,也帮助自己学习一下平时工作中没怎么用到的方法,看能不能提高开发效率.我当前使用的Angularjs版本是1.5.5也是目前最新的稳定版本,不 ...
随机推荐
- ceph实践: 搭建环境
作者:吴香伟 发表于 2014/09/26 版权声明:可以任意转载,转载时务必以超链接形式标明文章原始出处和作者信息以及版权声明 本节主要参考官网的ADDING/REMOVING OSDS章节. 同步 ...
- 利用(Tcmalloc) google-perftools优化Nginx和MySQL性能
一.安装libunwind wget http://download.savannah.gnu.org/releases/libunwind/libunwind-1.1.tar.gz 本地下载:htt ...
- 关于String中+与StringBuilder的问题
字符串连接可以通过两种方法实现,其中一种是在Java中提供的一个StringBuilder类(这个类只在J2SE5及以上版本提供,以前的版本使用StringBuffer类). 字符串是Java程序 ...
- c# json转换实例
用户实体: public class UserModel { public long? UserId { get; set; } public string UserName { get; set; ...
- html5实现摇一摇功能
原理:使用DeviceMotion实现,关于DeviceMotion介绍可以查看 https://developer.mozilla.org/en-US/docs/Web/Reference/Even ...
- nginx下搭建 Yii框架
因为启用了rewrite,导致css,js,images等静态文件也定向到index.php 我不得不重定向静态文件的路径 仅供参考: server { listen 80; server_name ...
- Android中如何收听特定应用安装成功的广播
一.manifest的配置 <receiver android:name=".AppReceiver"> <intent-filter> <actio ...
- 通过实现Countable接口来调用count函数
周六我一大早就来到公司,还有些客户工作没有收尾,还有写文档没写,还有写计划需要完善,我得抓紧.到了下午我发现大家陆陆续续的都到公司来了,有几个兄弟一来就开始工作了,每当有人自愿投入某一项工作时,我基本 ...
- 亲测——pycharm下运行第一个scrapy项目 ©seven_clear
最近在学习scrapy,就想着用pycharm调试,但不知道怎么弄,从网上搜了很多方法,这里总结一个我试成功了的. 首先当然是安装scrapy,安装教程什么的网上一大堆,这里推荐一个详细的:http: ...
- IAR之文件路径设置
1.命令解释 $PROJ_DIR$表示工程所在路径 $TOOLKIT_DIR$表示IAR安装目录所在头文件路径 \..\表示返回上一级目录. 2.头文件路径设置 打开工程文件,找到"opti ...