【问题标题】:How to include input fields from custom directives in angular forms?如何以角度形式包含来自自定义指令的输入字段?
【发布时间】:2017-01-20 22:42:52
【问题描述】:

我需要创建一个带有这样验证的简单表单 - https://jsfiddle.net/rohansh20/k7omkz7p/2/

<div ng-app="module1" ng-controller="ctrl1 as vm">
  <form novalidate name="vm.form1" class="css-form">
    <label>Name:
      <input type="text" name="Name" ng-model="vm.user.name" required />
    </label>
    <br />
    <label>E-mail:
      <input type="email" name="Email" ng-model="vm.user.email" required />
    </label>
    <br />
    <input type="submit" ng-click="vm.save(vm.form1, vm.user)" value="Save" />
  </form>
  <div>
    {{vm.result}}
  </div>  
  <pre>form = {{vm.form1 | json}}</pre>
</div>


angular.module('module1', []);

angular.module('module1').controller('ctrl1', function() {
  this.save = function(form, user) {
    if(form.$invalid) {
        this.result = 'Please correct the data entered';
      return;
    }
    this.result = 'User ' + user.name + ' with email ' + user.email + ' saved successfully';
  };
});

但我需要动态生成输入字段。所以我做了一个指令,可以转换成任何类型的输入字段 - https://jsfiddle.net/rohansh20/hdxj0np6/3/

<div ng-app="module1" ng-controller="ctrl1 as vm">
  <form novalidate name="vm.form1" class="css-form">
    <custom-input name="Name" type="text" model="vm.user.name" required="true">
    </custom-input>
    <br />
    <custom-input name="Email" type="email" model="vm.user.email" required="true">
    </custom-input>
    <br />
    <input type="submit" ng-click="vm.save(vm.form1, vm.user)" value="Save" />
  </form>
  <div>
    {{vm.result}}
  </div>
  <pre>form = {{vm.form1 | json}}</pre>
</div>

var app = angular.module('module1', []);

app.controller('ctrl1', function() {
  this.save = function(form, user) {
    if(form.$invalid) {
        this.result = 'Please correct the data entered';
      return;
    }  
    this.result = 'User ' + user.name + ' with email ' + user.email + ' saved successfully';
  };
});

app.directive('customInput', function($compile) {
  return {
    restrict: 'E',
    link: function(scope, element, attributes) {
      var labelElement = angular.element('<label/>'),
        name = attributes.name,
        type = attributes.type,
        ngModelString = attributes.model,
        required = attributes.required,
        inputElement = angular.element('<input/>');
      inputElement.attr('ng-model', ngModelString);
      inputElement.attr('name', name);
      inputElement.attr('type', type);
      if (required) {
        inputElement.attr('required', 'required');
      }
      labelElement.append(name + ': ');
      labelElement.append(inputElement);
      $compile(labelElement)(scope);
      element.replaceWith(labelElement);
    }
  }
});

小提琴是我正在尝试制作的简化版本。 问题是这些字段,即使编译和呈现完美(可以通过检查 HTML 看到),也没有作为父表单控件的一部分包含在内。这可以在两个小提琴中显示的表单控件对象中看到。因此,无法确定表单的有效性,并且两种表单在提交无效输入时表现不同。

我需要第二个小提琴中的表单控件具有正确的属性值,并让子控件及其属性像第一个小提琴一样。这甚至可以使用自定义指令吗?我需要进行哪些更改才能完成这项工作?

注意 - 该指令将涉及动态创建 HTML 的复杂操作,因此必须在指令的链接函数中完成。带有多个 ngIf 的指令模板将无法正常工作。

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-forms


    【解决方案1】:

    为了不丢失父表单的绑定,请将其包含在自定义表单指令中

    在你的指令中

        (function () {
        'use strict';
    
        angular
            .module('myApp')
            .directive('customInput', customInput)
    
    
    
    
    
        customInput.$inject = ['$compile'];
        /* @ngInject */
        function customInput ($compile) {
    
    
            var directive = {
                templateUrl: 'app/custom-input.html',
                restrict: 'E',
                transclude: true,
                require: "?^form",
                compile: compile,
                controller:CustomInputController,
                controllerAs:'vm',
                scope:{
                    inputType:'=',
                    inputValue:'='
                }
            };
    
            return directive;
            function CustomInputController($scope){
                var vm = this;
    
    
            }
            function compile(element, attributes){
    
                return {
                    pre: preLink,
                    post: postLink
                }
            }
            function preLink (scope,element,attrs, form, transclude){
    
            }
            function postLink (scope,element,attrs, form, transclude){
                scope.currentForm = form;
    
                $compile(element.contents())(scope);
            }
        }
    
    })();
    

    在你的指令 html 模板中

    <input type="inputType" ng-model="inputValue">
    

    当你调用你的指令时

       <br-input type="text"
              input-value="vm.user.email"
              inputname="name"
              input-required ="true">
       </br-input>
    

    【讨论】:

      猜你喜欢
      • 2015-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-01
      • 2016-03-29
      • 2023-03-27
      相关资源
      最近更新 更多