AngularJS - 直接在< form>上声明ng-model。元件(AngularJS - declare ng-model directly on the <form> element)

其他开发 IT屋
百度翻译此文   有道翻译此文
问 题

In AngularJS, is there any way to declare ng-model directly on the <form> element instead of having to do it on every single control/input of that form and then be able to access the values of the controls in the controller through their names?

Specifically, if you have a form like this,

<form>
  <input type="text" name="email">
  <input type="text" name="age">
</form>

typically, you'd do something like this,

<form>
  <input type="text" ng-model="user.email">
  <input type="text" ng-model="user.age">
<form>

which then gives you access to the user object and its properties in the controller:

$scope.user
$scope.user.email
$scope.user.age

I would like to do something like this instead:

<form ng-model="user">
  <input type="text" name="email">
  <input type="text" name="age">
</form>

and then be able to access the values in the controller:

$scope.user.email
$scope.user.age

The reason I'm asking is that I'm angularizing an existing web project and some of the forms have easily 20 or 30 controls and defining the ng-model individually seems like an overkill.

All the form examples that I'm able to find declare the ng-model on the individual controls. I was also able to dig up this ticket which basically says that something like this would require a major AngularJS overhaul, so I suspect it may not be possible. But the ticket is from a year ago and perhaps things have changed since then.

解决方案

Out of the box; no. But you can quite easily write your own directive that does the trick.

app.directive('lazyFormModel', function() {
  return {
    require: ['form'],

    compile: function compile(tElement, tAttrs) {

      var modelName = tAttrs.lazyFormModel;

      angular.forEach(tElement.find('input'), function(e) {
        var $e = angular.element(e);
        var name = $e.attr('name');
        $e.attr('ng-model', modelName + '.' + name);
      });
    }
  };
});

The above will create a directive that will loop through all the containing input elements and stamp an ng-model attribute on them based on the name value. Attach this to a form element and you're good to go:

<form lazy-form-model="user">
  <input type="text" name="email">
  <input type="text" name="age">
</form>

See it in action: http://plnkr.co/edit/O7ais3?p=preview

Edit

As a side note; you can extend this to fit other manipulations too: like custom validations and/or html layout.

Edit

Would you know how I could extend this to work with multiple checkboxes of the same name but different values (a checklist type of input)?

Something like this should handle checkboxes:

angular.forEach(tElement.find('input'), function(e) {
  var $e = angular.element(e);
  var name = $e.attr('name');

  var modelProperty = modelName + '.' + name;

  if($e.attr('type') == 'checkbox') {
    modelProperty += '.' + $e.attr('value');
  }

  $e.attr('ng-model', modelProperty);
});

Updated the plunker.

本文地址:IT屋 » AngularJS - declare ng-model directly on the &lt;form&gt; element

问 题

在AngularJS中,有没有办法直接在< form> 元素上声明ng-model,而不必在每个控件/然后能够通过他们的名字访问控制器中的控件的值?



具体来说,如果您有这样的表单,



 < form> 
< input type =“text”name =“email”>
< input type =“text”name =“age”>
< / form>


通常情况下,您会这样做,



 < form> 
< input type =“text”ng-model =“user.email”>
< input type =“text”ng-model =“user.age”>
< form>


然后您可以访问控制器中的用户对象及其属性:



  $ scope.user 
$ scope.user.email
$ scope.user.age


我想这样做:

 < form ng-model =“user”> 
< input type =“text”name =“email”>
< input type =“text”name =“age”>
< / form>


然后可以访问控制器中的值:

  $ scope.user.email 
$ scope.user.age


我问的原因是,我正在对现有的Web项目进行角色化,并且一些表单容易有20或30个控件,并且单独定义ng模型看起来像是过度杀伤。

我可以找到的所有表单示例都在各个控件上声明ng模型。我也能够挖掘这个机票,基本上说这样的东西会需要进行重大的AngularJS检修,所以我怀疑这可能是不可能的。但这张票是一年前的,也许事情从那时起就发生了变化。

解决方案

开箱即用;没有。但是你可以很容易地编写你自己的指令来实现这一点。



  app.directive('lazyFormModel',function(){ 
return {
require:['form'],

编译:function compile(tElement,tAttrs){

var modelName = tAttrs.lazyFormModel ;

angular.forEach(tElement.find('input'),function(e){
var $ e = angular.element(e);
var name = $ ('name');
$ e.attr('ng-model',modelName +'。'+ name);
});
}
} ;
});


以上将创建一个指令,循环遍历所有包含输入元素,并根据名称值为其添加 ng-model 属性。将这个附加到一个表单元素,你很好去:



 < form lazy-form-model =“user” > 
< input type =“text”name =“email”>
< input type =“text”name =“age”>
< / form>


实际操作: http://plnkr.co/edit/O7ais3?p=preview


$ b 编辑



作为一个侧面说明;你可以扩展它以适应其他操作:如自定义验证和/或html布局。

编辑


可以扩展它以使用多个相同名称但不同值的复选框(一个清单类型的输入)?



类似这样的应该处理复选框:

  angular.forEach(tElement.find('input'),function(e){
var $ e = angular.element(e);
var name = $ e.attr('name');

var modelProperty = modelName +'。'+ name;

if($ e.attr('type')=='checkbox'){
modelProperty + ='。'+ $ e.attr('value');
}

$ e.attr('ng-model',modelProperty);
});


更新了 plunker


本文地址:IT屋 » AngularJS - 直接在&lt; form&gt;上声明ng-model。元件

官方微信
扫一扫关注IT屋
微信公众号搜索 “ IT屋 ” ,选择关注
与百万开发者在一起