返回介绍

预定义的 FormController

发布于 2024-12-24 22:41:42 字数 8315 浏览 0 评论 0 收藏 0

18.11. 预定义的 FormController

前面的“表单控制”那章,实际上讲的就是 `FormController` ,只是那里是从 scope 中获取到的引用。现在从指令定义的角度,来更清楚地了解 `FormController` 及 `NgModelController` 是如何配合工作的。

先说一下, `form` 和 `ngForm` 是官方定义的两个指令,但是它们其实是同一个东西。前者只允许以标签形式使用,而后者允许 EAC 的形式。DOM 结构中, form 标签不能嵌套,但是 ng 的指令没有这个限制。不管是 `form` 还是 `ngForm` ,它们的 controller 都被命名成了 form 。 所以 `require` 这个参数不要写错了。

`FormController` 的几个成员是很好理解的:

`$pristine` 表单是否被动过
`$dirty` 表单是否没被动过
`$valid` 表单是否检验通过
`$invalid` 表单是否检验未通过
`$error` 表单中的错误
`$setDirty()` 直接设置 `$dirty` 及 `$pristine`
  <div ng-controller="TestCtrl">
    <div ng-form test>
      <input ng-model="a" type="email" />
      <button ng-click="do()">查看</button>
    </div>
  </div>
  var app = angular.module('Demo', [], angular.noop);

  app.directive('test', function(){
    var link = function($scope, $element, $attrs, $ctrl){
      $scope.do = function(){
        //$ctrl.$setDirty();
        console.log($ctrl.$pristine); //form是否没被动过
        console.log($ctrl.$dirty); //form是否被动过
        console.log($ctrl.$valid); //form是否被检验通过
        console.log($ctrl.$invalid); //form是否有错误
        console.log($ctrl.$error); //form中有错误的字段
      }
    }

    return {compile: function(){return link},
            require: 'form',
            restrict: 'A'}
  });

  app.controller('TestCtrl', function($scope){
  });

`$error` 这个属性,是一个对象, key 是错误名, value 部分是一个列表,其成员是对应的 `NgModelController` 的实例。

`FormController` 可以自由增减它包含的那些,类似于 `NgModelController` 的实例。在 DOM 结构上,有 ng-modelinput 节点的 `NgMoelController` 会被自动添加。

`$addControl()` 添加一个 conroller
`$removeControl()` 删除一个 controller

这两个手动使用机会应该不会很多。被添加的实例也可以手动实现所有的 `NgModelController` 的方法

  <div ng-controller="TestCtrl">
    <bb />
    <div ng-form test>
      <input ng-model="a" type="email" />
      <button ng-click="add()">添加</button>
    </div>
  </div>
 1   var app = angular.module('Demo', [], angular.noop);
 2   
 3   app.directive('test', function(){
 4     var link = function($scope, $element, $attrs, $ctrl){
 5       $scope.add = function(){
 6         $ctrl.$addControl($scope.bb);
 7         console.log($ctrl);
 8       }
 9     }
10   
11     return {compile: function(){return link},
12             require: 'form',
13             restrict: 'A'}
14   });
15   
16   app.directive('bb', function(){
17     var controller = function($scope, $element, $attrs, $transclude){
18       $scope.bb = this;
19       this.$name = 'bb';
20     }
21   
22     return {compile: angular.noop,
23             restrict: 'E',
24             controller: controller}
25   });
26   
27   app.controller('TestCtrl', function($scope){
28   });

整合 `FormController` 和 `NgModelController` 就很容易扩展各种类型的字段:

  <div ng-controller="TestCtrl">
    <form name="f">
      <input type="my" ng-model="a" />
      <button ng-click="show()">查看</button>
    </form>
  </div>
 1   var app = angular.module('Demo', [], angular.noop);
 2   
 3   app.directive('input', function(){
 4     var link = function($scope, $element, $attrs, $ctrl){
 5       console.log($attrs.type);
 6       var validator = function(v){
 7         if(v == '123'){
 8           $ctrl.$setValidity('my', true);
 9           return v;
10         } else {
11           $ctrl.$setValidity('my', false);
12           return undefined;
13         }
14       }
15   
16       $ctrl.$formatters.push(validator);
17       $ctrl.$parsers.push(validator);
18     }
19   
20     return {compile: function(){return link},
21             require: 'ngModel',
22             restrict: 'E'}
23   });
24   
25   app.controller('TestCtrl', function($scope){
26       $scope.show = function(){
27         console.log($scope.f);
28       }
29   });

虽然官方原来定义了几种 type ,但这不妨碍我们继续扩展新的类型。如果新的 type 参数值不在官方的定义列表里,那会按 text 类型先做处理,这其实什么影响都没有。剩下的,就是写我们自己的验证逻辑就行了。

上面的代码是参见官方的做法,使用格式化的过程,同时在里面做有效性检查。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文