Create a form container with Angular JS component

2019-09-08 18:19发布

I am using Angular JS 1.5.6 and I would like to use only component and not directive.

I have more than 5 views using a form in my application. The style of the form is exactly the same in all the views, it is only the content of the form that changes. I have made components (input, button, etc..) and I would like to create a component for the form, it would be like a container component, in which I can put different components. In view A, the form will contain 1 button and 1 input, in view B the form will contain 2 button and 2 inputs, etc... But I don't know if it is possible to do it and how to dow it. I have plnkered this. I would like to create a component for the form.

<!DOCTYPE html>
<html ng-app="MyApp">

<head>
  <link data-require="bootstrap-css@3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.6/angular.min.js"></script>
  <script src="script.js"></script>
  <script src="myInput.js"></script>
  <script src="myButton.js"></script>
</head>

<body ng-controller="MyCtrl">
  <div class="container">
    <h2>My form</h2>
    <form role="form">
      <my-input label="Firstname"></my-input>
      <my-input label="Lastname"></my-input>
      <my-button label="Submit"></my-button>
    </form>
  </div>
</body>

</html>

2条回答
够拽才男人
2楼-- · 2019-09-08 19:12

There are two basic problems need to be solved in your form container:

  • Dynamic template for your form

  • Handle summit should be run outside of your component.

I solve two problems by

  • Read template via attrs property

  • Pass handler function as a binding property

Code for form component:

  angular.module('MyApp').component('myForm', {
    templateUrl: function($element, $attrs) {
      return $attrs.template; // read template file from component attribute
    },
    controller: MyFormController,
    bindings: {
      label: '@',
      summitHandler: '&' // call to function outside of component via this property
    }
  });

In MyFormController, we need handle summit event by calling to summitHandler function passed via binding property:

function MyFormController($scope, $element, $attrs) {
      var ctrl = this;
      ctrl.summitForm = function(data) {
        // call handler with data summited
        var handler = ctrl.summitHandler();
        handler(data);
      }
}

That all for our form container component.

Now you can add my-form with:

<my-form label="Personal Info" template="myForm.html" summit-handler="ctrl.myFormHandler"></my-form>

Property ctrl.myFormHandler will be a function handling event in myCtl with:

ctrl.myFormHandler = function(data){
    console.log('receive test summit:' + data);
    ctrl.dataReceived = data;
}

See it run here in Plunk.

Typing in the age field, you can see it will be passed to outside of form. Extend it with more features as you want.

查看更多
疯言疯语
3楼-- · 2019-09-08 19:19

Look at this project:

http://kelp404.github.io/angular-form-builder/

If you want to implement this yourself you will need to create a template dynamically and compile it before it's injected into the DOM. This project can be useful:

https://github.com/incuna/angular-bind-html-compile

It's directive but it will inject and compile your form elements (components or directives) for you:

<div bind-html-compile="formElements.input1"></div>
查看更多
登录 后发表回答