11

so I have a component with a template containing a form.

mycomponent.html:

<div>
    <form name="myForm"> 
        <!-- more html code -->
    </form>
</div>

How can I access myForm inside the component controller? Currently I'm injecting $scope to get it from that. Or is that the only way to get the form?

Edit: Added some code to better illustrate in javascript

angular.module('example')
.component('myComponent', {

    templateUrl: 'mycomponent.html',
    controller: function($scope) {
         $scope.myForm // This works
         this.myForm // undefined, can I access it through the component scope instead of $scope somehow? 
    }
 });
Luna
  • 349
  • 1
  • 4
  • 12
  • Generally you bind you the elements in the form in angular, rather than dealing with the form directly. Is there some reason you need to access the form element itself? – Dave Mar 17 '16 at 15:51
  • 2
    I wanted to check the $pristine, $valid e.t.c. – Luna Mar 17 '16 at 15:54

2 Answers2

25

The name attribute of a form is what angular uses to decide what to bind to. So, if you're using the controllerAs syntax, you have to use that in the form name:

  <body ng-controller="MainCtrl as vm">
    <form name='vm.myForm'>
    </form>
  </body>

This will allow you to refer to it in your controller without using $scope, but only after the controller has been successfully created:

app.controller('MainCtrl', function($scope, $timeout) {

    var vm = this;

    console.log(vm.myForm);  // undefined

    $timeout(function() {
        console.log(vm.myForm);  // FormController object
    }, 100);
});

Here is a working plunk.

Dave
  • 4,375
  • 3
  • 24
  • 30
  • 1
    Thanks, that worked with a slight modification since I'm using components and don't have access to as far as I know "mainctrl as vm".
    as the name and then accessable as this in the angular component.
    – Luna Mar 17 '16 at 20:45
  • 2
    Are you using angular 1.5? It automatically adds `$ctrl` as a default value for `controllerAs`, even for components. – Dave Mar 17 '16 at 21:02
  • Yes, angular 1.5 and I see. Good to know for the future! – Luna Mar 17 '16 at 23:16
  • 3
    Yes this
    works for components but as royka pointed out you can access that in postLink hook
    – Marco C. Jan 21 '17 at 00:53
  • I do not approve of `$timeout` usage, when it can be handled by a simple scope function from template and have a form for an argument there. More complex example [here](https://jsbin.com/noqacu/3/edit?html,js,console). – Eugene Apr 03 '17 at 12:24
  • Yeah, I'm sure there's a better way to wait until the controller has been created to do stuff like that. – Dave Apr 03 '17 at 14:57
  • 1
    @Dave there is a .$onInit function for components that is for use to run after the component is initialized and ready for use, so using this example `vm.$onInit => () { console.log(vm.myForm);}` – BlackICE Aug 01 '18 at 19:53
1

Use the name syntax but also a components postLink lifecycle hook, that function is called once a template and controller have been connected see https://docs.angularjs.org/guide/component

royka
  • 1,570
  • 2
  • 12
  • 10