学习笔记-AngularJs(八)

在使用form.FormController和ngModel.NgModelController之前,先来学习一下怎么一个ng-model-options指令,觉得怎么这个指令挺好用的,我们知道ng-model是可以实现数据的双向绑定,至于双向数据绑定这个概念时必须要清楚的,都是这样的一个过程,view->scope和scope->view,只要双向绑定的element都是走怎么一个过程的,那么这个ng-model-options,就是可以实现对延迟更新、如何触发更新、时区(timezone针对input[type=‘date‘]等)等的控制,来看一下官网的例子:

//github上的block-example/表单操作-11/ng-model-options.htmlangular.module(‘optionsExample‘, [])
.controller(‘ExampleController‘, [‘$scope‘, function($scope) {
  $scope.user = { name: ‘say‘, data: ‘‘ };

  $scope.cancel = function(e) {
    if (e.keyCode == 27) {
      $scope.userForm.userName.$rollbackViewValue();
    }
  };
}]);
<div ng-controller="ExampleController">
  <form name="userForm">
    Name:
    <input type="text" name="userName"
           ng-model="user.name"
           ng-model-options="{ updateOn: ‘blur‘,debounce: 1000 ,getterSetter: false  }"
           ng-keyup="cancel($event)" /><br />

    Other data:
    <input type="text" ng-model="user.data" /><br />
  </form>
  <pre>user.name = <span ng-bind="user.name"></span></pre>
</div>

updateOn:可以写入事件名字,将此element按所写事件触发更新

debounce:当我们写进keydowm事件的时候,我需要的是它尽可能说是当我输入完毕后,再去触发更新,那么这个时候我们可以延迟个1s!

getterSetter:为true的时候,则是指element的值是从函数return过来滴!

我们看一下这里, $scope.userForm.userName.$rollbackViewValue(); userForm、userName是什么鬼?眼尖的可以看到是表单的name和input[name=‘userName‘],那么其实可以怎么理解表单实例可以随意地使用name属性暴露到scope中,于是在$scope就可以使用表单实例了,便可以使用表单控制器的属性和方法了!

form.FormController是啥?

FormController跟踪所有input和form的各种状态的控制,如被有效/无效/已交互/未交互。官网文档:http://docs.angularjs.cn/api/ng/type/form.FormController

其拥有的方法:

$rollbackViewValue(); $commitViewValue(); $addControl(); $removeControl(); $setValidity(); $setDirty(); $setPristine(); $setUntouched(); $setSubmitted();

$addControl()  //添加ngModel controller ,ngModel会自动添加,除非自定义指令或许会用上
$removeControl()  //与$addControl()相反
$setValidity()  //在自定义表单检验有着很大作用

$rollbackViewValue() //这个我是这样理解的,回滚到上一个ViewValue

拥有的属性:

$pristine(form没被动过)  $dirty(form被动过) $valid(全部验证通过) $invalid(验证不通过) $submitted
$error
    email、max、maxlength、min、minlength、number、pattern、required、url、date、datetimelocal、time、week、month

给一个官网的例子(使用表单控制器的属性和方法怎么去验证input的正确性):


//github上的block-example/表单操作-11/ng-form.html,其它类型的input[type=*]验证也都更新到github了
<!doctype html>
<html ng-app=‘formExample‘>
    <head>
        <meta charset="utf8"/>
        <script src="http://code.angularjs.org/angular-1.0.1.min.js"></script>
        <style>
         .my-form {
           -webkit-transition:all linear 0.5s;
           transition:all linear 0.5s;
           background: transparent;
         }
         .my-form.ng-invalid {
           background: red;
         }
        </style>
        <script>
          angular.module(‘formExample‘, [])
            .controller(‘FormController‘, [‘$scope‘, function($scope) {
              $scope.userType = ‘guest‘;
              $scope.email = ‘[email protected]‘;

              var list = $scope.list = [];

              $scope.submit = function() {
                     if($scope.userType){ list.push(this.userType);}
                     if($scope.email){  list.push(this.email);}
                      // console.log(this.userType+","+this.email);
                      // console.log($scope.list);
                  };
            }]);
        </script>
    </head>
    <body>
        <!--表单控制器-->
        <form name="myForm" ng-submit="submit()"  ng-controller="FormController" class="my-form" >
          userType: <input name="input" type="text" ng-model="userType" required>
          <span class="error" ng-show="myForm.input.$error.required">Required!</span><br>  <!--这里的意思是没有填的话就会显示-->
          email:  <input name="email" type="email"  ng-model="email">
                <span class="error" ng-show="myForm.email.$error.email">Wrong Email!</span>
          <br>
          <input type="submit" value="提交" id="submit" />
          <tt>userType = {{userType}}</tt><br>
          <tt>email = {{email}}</tt><br>
          <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br> <!--表单的input的有效为true-->
          <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br> <!--表单的input的$error-->
          <tt>myForm.email.$valid = {{myForm.email.$valid}}</tt><br> <!--表单的input的有效为true-->
          <tt>myForm.email.$error = {{myForm.email.$error}}</tt><br> <!--表单的input的$error-->
          <tt>myForm.$error.email = {{!!myForm.$error.email}}</tt><br>
          <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>  <!--$error属性的required-->
          <tt>myForm.$valid = {{myForm.$valid}}</tt><br>        <!--有效效为true-->
          <tt>myForm.$invalid = {{myForm.$invalid}}</tt><br>    <!--无效为true-->
          <tt>myForm.$pristine= {{myForm.$pristine}}</tt><br>   <!--与表单有相互作用为true-->
          <tt>myForm.$dirty= {{myForm.$dirty}}</tt><br>   <!--与表单无相互作用为true-->
          <tt>myForm.$submitted = {{myForm.$submitted}}</tt><br>
          <tt>提交的数据:{{list|json}}</tt>
         </form>
    </body>
</html>

<!-- If the name attribute is specified, the form controller is published onto the current scope under this name. -->

<!--表单阻止了表单默认action提交的方式,改用ng-submit或ng-click对表单进行绑定,具体操作看列子-->

<!-- <form [name=""]>...</form> 等价于 <div ng-form=‘##‘></div> 控制器为name属性的值 -->

具体可以看代码!

ngModel.NgModelController是啥?

NgModelController 为ngModel指令提供了API。该控制器包含数据双向绑定服务、验证、Value格式化和解析、CSS更新。它不包含任何逻辑处理DOM渲染或DOM event,这样的DOM相关逻辑应使用其他指令,NgModelController用来控制元素的数据绑定。Angular默认提供许多关于input元素 DOM逻辑处理。官网文档:http://docs.angularjs.cn/api/ng/type/ngModel.NgModelController

其拥有的方法:

$render(); $isEmpty(value); $setValidity(validationErrorKey, isValid); $setPristine(); $setDirty(); $setUntouched(); $setTouched(); $rollbackViewValue(); $validate(); $commitViewValue(); $setViewValue(value, trigger);

$render: angular 会把 $modelValue 经过 $formatters 得出来的值放入 $viewValue中,(这时 $viewValue = $modelValue 经过 $formatters) 然后触发我们写好的 $render . 跟着$setViewValue(value, trigger);一起使用。

$setViewValue:scope改变$modelValue,使用$setViewValue(),改变$viewValue

$setValidity:使用这个配合$parsers可以实现表单自定义验证

拥有的属性:

$viewValue  //界面显示的数据

$modelValue  //$scope上面的value

$parsers  //在view->model的时候会触发的一个函数组,无论什么时候Model发生改变,所有的ngModelController.$formatters(model发生改变时触发数据有效验证和格式化转变)数组中的function将排队执行,所以在这里每一个function都有机会去格式化model的值,并且通过NgModelController.$setValidity修改空间的验证状态。

$formatters //在model->view的时候会触发的一个函数组, 无论任何时候用户与控件发生交互,将会触发NgModelCtroller.$setViewValue。这时候轮到执行NgModelController.$parsers(当控件从dom取值之后,将会执行这个数组中的所有方法,对值进行审查过滤或转换,也进行验证)数组中的所有方法。

$validators $asyncValidators $viewChangeListeners $error $pending $untouched $touched $pristine $dirty $valid $invalid $name

那么多个属性都差不多,是不是关系很密切勒!双向绑定的机制可以在$parsers和$formatters可以体现出来,通过这些我们可以在view->scope做类似表单验证(自定义)的功能(配合$setValidity(validationErrorKey, isValid);),scope->view数据格式自定义等操作(配合$setViewValue(value, trigger);),可以看一下下面的这个例子(https://github.com/xiaobin5201314/AngularJS-Learning/blob/master/block-example/表单操作-11/ng-model.html):


var custom = angular.module(‘customControl‘, [‘ngSanitize‘]);

custom.directive("noxiaobin", function () {
return {
restrict: "A",
require: "?ngModel",
link: function (scope, element, attrs, ngModel) {
if (!ngModel) return;
ngModel.$parsers.push(function (v) { //传说中的验证器

if (v != "xiaobin") {
ngModel.$setValidity(‘noxiaobin‘, true); //通过获取从dom过来的值,然后进行验证,使用$setValidity(‘noxiaobin‘, true);改变noxiaobin的值,然后反馈会dom
return v;
} else {
ngModel.$setValidity(‘noxiaobin‘, false);
return undefined;
}

});
}
}
});


custom.directive(‘contenteditable‘, [‘$sce‘, function($sce) {
return {
restrict: ‘A‘, //指定该指令是为属性类型的指令
require: ‘?ngModel‘, // 与ngModel指令的相互交流
link: function(scope, element, attrs, ngModel) { //scope分别是指令作用的作用域,element触发指令的元素,attrs是element的属性集合,ngmodel是控制器就是引入的ngModel
if (!ngModel) return;


// output data to the view
ngModel.$render = function() {
element.html($sce.getTrustedHtml(ngModel.$viewValue || ‘‘)); //$viewValue的值进行format
};


//对element的监听
element.on(‘blur keyup change‘, function() {
scope.$evalAsync(read); //执行read方法
});
read(); // 初始化


// Write data to the model
function read() {
var html = element.html();
// When we clear the content editable the browser leaves a <br> behind
// If strip-br attribute is provided then we strip this out
if ( attrs.stripBr && html == ‘<br>‘ ) {
html = ‘‘;
}


ngModel.$setViewValue(html); //获取ViewValue,设置$viewValue
}

}
};
}]);

 
    <form name="myForm">
         <div contenteditable
              name="myWidget" ng-model="userContent"
              strip-br="true"
              required>点击编辑</div>
          <span ng-show="myForm.myWidget.$error.required">Required!</span>

          <input type="text" name="email" ng-model="email" noxiaobin />
          <span ng-show="myForm.email.$error.noxiaobin">Value nerver have xiaobin!</span>
         <hr>
         <textarea ng-model="userContent"></textarea>
    </form>

以上有两个指令分别是

1、view->scope,配合$setValidity(validationErrorKey, isValid);进行表单验证,通过反馈回view的noxiaobin来判断是否显示

2、scope->view,使用$setViewValue(value, trigger);设置view的值,然后触发$render,对其进行格式化

3、代码下载:https://github.com/xiaobin5201314/AngularJS-Learning

对于ngModel.NgModelController确实有些绕,也有些地方还是不懂,不过也有些文章写得还是比较明晰的,如:http://sentsin.com/web/659.html,如果对ngModel.NgModelController有那些更加全,或是更加详细的资料可以拿给我学习学习!!!

时间: 2024-10-25 17:27:27

学习笔记-AngularJs(八)的相关文章

学习笔记-AngularJs(十)

前面一直在说自定义指令,但是却一直没有一次系统地去了解,现在需要我们一起来学习如何去使用自定义指令,去丰富html标签.属性,实现多元化.多功能的标签(或是属性).辣么,啥是指令?要了解指令,首先需要了解AngularJs的HTML编译器,简单地说让浏览器认识你自定义指令或是Angular的指令集,将其行为运用到DOM上(视图),分两个过程编译和链接,编译阶段是遍历DOM并且收集所有的相关指令,生成一个链接函数:链接阶段是给通过编译阶段调用所说的链接函数来将模板与作用域链接起来,绑定一个作用域,

Servlet学习笔记(八)—— 自定义过滤器的编写改进:自定义实现FilterChain

笔记六中实现了三种过滤器:字符编码过滤.登录权限过滤.敏感词过滤,但是有个缺陷就是,限定了过滤顺序,而不能实现先进行request过滤,最后response过滤,并且中间几项过滤的顺序不能动态改变.所以这里做个改进,实现一个过滤顺序的FilterChain. 多个Filter的执行顺序在这篇博文中得到很仔细的讲解,总结一点,多个过滤器的执行顺序是根据web.xml中不同<filter-mapping>的顺序来先后执行的,比如: <?xml version="1.0"

汇编入门学习笔记 (八)—— 转移指令

疯狂的暑假学习之  汇编入门学习笔记 (八)--  转移指令 參考: <汇编语言> 王爽 第9章 能够改动ip或者同一时候改动cs和ip的指令统称为转移指令. 8086CPU转移行为分为: 段内转移:仅仅改动ip 段间转移:同一时候改动cs和ip 段内转移按ip改动的范围可分为: 短转移:ip改动范围 -128~127 近转移:ip改动范围 -32768~32767 转移指令分为: 无条件转移指令.如 jmp 条件转移指令 循环指令.如 loop 过程. 中断. 1. offset,nop指令

学习笔记-AngularJs(九)

到目前为止,我们所做的学习案例都是没有加任何动画效果的,对于以往来说,我们经常会去使用一些动画插件或是css框架(如:animate.css)来点缀我们的网页,这样显得生动,高大上,那么接下来我们可以学习一下,怎么在AngularJs下来实现叼酷炫的动画操作,主要使用的命令是ngAnimate. 与之前的ngResource,ngRoute一样,需要注入ngAnimate和引入ng-animate.js才可以使用此服务,想在你的angular应用程序使用ngAnimate来实现动画功能,前提条件

Spring3.0官网文档学习笔记(八)--3.4.3~3.4.6

3.4.3 使用depends-on 使用depends-on可以强制使一个或多个beans先初始化,之后再对这个bean进行初始化. 多个bean之间用",".";"." "隔开. <bean id="beanOne" class="ExampleBean" depends-on="manager"/> <bean id="manager" cla

Nodejs学习笔记(八)--- Node.js + Express 实现上传文件功能(felixge/node-formidable)

目录 前言 formidable简介 创建项目并安装formidable 实现上传功能 运行结果 部分疑惑解析 写在之后 前言 前面讲了一个构建网站的示例,这次在此基础上再说说web的常规功能----文件上传,示例以一个上传图片的功能为例子 上传功能命名用formidable实现,示例很简单! PS:最近比较忙,距上一次更新已经比较久了^_^! formidable简介 nodejs原生实现上传还是比较麻烦,有兴趣的自已去参考一下网上有网友写的代码 这里选择了formidable,也是githu

学习笔记-AngularJs(三)

学习笔记-AngularJs(二)写了个所有程序语言入门时都必须要写的Hello World,那么从现在开始做那个之前说过的互联网大佬介绍的学习例子,当然这里开始会慢慢按照之前说过的目录来搭建这个学习的demo,将控制器.过滤器.指令.服务.基本配置都独立成一个个js文件,直接贴张效果图: (有点简陋,之后再把样式写好看些!) 这里实现的功能是这样的,在前台遍历phones的对象数组,然后可以按照年龄和名字排序,也可以通过输入字符串过滤检索.代码如下: html: <!doctype html>

疯狂Android讲义 - 学习笔记(八)

第10章 Service与BroadcastReceiver 10.1 Service简介 Service组件也是可执行的程序,有自己的生命周期,创建.配置Service与创建.配置Activity的过程基本相似.Service一直在后台运行,没有用户界面. 10.1.1 创建.配置Service 需要2个步骤:1 定义基础Service的子类,2 在AndroidManifest.xml文件中配置Service. Service与Activity都是从Context派生出来的,因此都可以调用C

RxJava 学习笔记(八) --- Combining 结合操作

@(Rxjava学习笔记) RxJava 学习笔记(八) - Combining 结合操作 RxJava 学习笔记八 Combining 结合操作 StartWith 在数据序列的开头插入一条指定的项 Merge 将多个Observable合并为一个 MergeDelayError 将多个Observable合并为一个 Zip 使用一个函数组合多个Observable发射的数据集合然后再发射这个结果 CombineLatest 当两个Observables中的任何一个发射了一个数据时通过一个指定

Mysql学习笔记(八)索引

原文:Mysql学习笔记(八)索引 PS:把昨天的学习内容补上...发一下昨天学的东西....五月三日...继续学习数据库... 学习内容: 索引.... 索引的优点: 1.通过创建唯一索引,可以保证数据库每行数据的唯一性... 2.使查找的速度明显加快... 3.当使用分组和排序进行查询时,可以缩短时间... 索引的缺点: 1.维护索引需要耗费数据库的资源... 2.索引需要占用磁盘空间... 3.对表进行增删改的时候,由于索引的存在,时间会有所增加... 索引的分类... 普通索引和唯一索引