Angular.js: FormController: attach to component controller?

Created on 10 Feb 2016  路  13Comments  路  Source: angular/angular.js

The new component support in 1.5 is great, but it seems to interact badly with FormController. With a very simple component like such:

someModule.component('customComponent', {
  template: '<form name="$ctrl.form">Is form valid? {{ $ctrl.form.$valid }}</form>',
  controller: ['$scope', function($scope) {
    this.$onInit = function() {
      console.log("FormController:");
      console.log(this.form);
    };
  }]
});

all seems well on-screen, as it will correctly show Is form valid? true. However, the console.log in the customComponent controller can't find the FormController that should be bound to it via name="$ctrl.form". I also checked $scope.form and $scope.$ctrl.form to make sure it wasn't a this-binding issue, but no luck.

Here is a Plunker showing the issue in action: http://plnkr.co/edit/P8gKwz6koHeoXRHdhoGl

Am I missing something obvious?

$compile inconvenient feature

Most helpful comment

@setry14 You can use the $postLink lifecycle hook added in 1.5.3.

All 13 comments

The only guarantee for the $onInit hook is that the required controllers will be available. The FormController you are trying to access is not required and it uses a different mechanism, so I am afraid you are "stuck" with using a post-link function for grabbing that (or try to access it asynchronously if you know your template doesn't load any partial from the server).

Maybe we could add an $afterViewInit hook or something, that would be called after the post-linking phase.

@petebacondarwin, wdyt ?

@gkalpak That would be awesome if you could add an $afterViewInit hook after post linking. I think after seeing more of 1.5, people are going to be requesting more hooks that are included in angular 2 because it is easier to manage your code in the controller vs in a directive especially if you are using ES2015 which make writing elaborate directives more of pain and would ease the transition to angular 2 even further.

The form is also set on the scope - there's no way (yet) to attach it to the controller.

(Not that it's related to the lifecycle hook, but) it is possible by using name="$ctrl.form" (as in OP's example), since $ctrl is just a reference to the controller on the scope.

The important thing about the hook is that it will be called after everything is set (either on the scope or on the controller), so the user doesn't try to access properties that don't yet exist.

Oh, yes, obviously. Thanks for correcting that.

Sounds interesting. Is that a hook in A2? What are its exact semantics? Does someone want to knock up a PR?

Yes, it's a hook in ng2. I'm not sure about the exact semantics (and I didn't dive into the code, since the semantics won't much ng1 semantics 1-to-1), but from the description of it it sounds similar to right after ng1's post-linking.

The ng2 docs on lifecycle hooks is still WIP, but here is demo plnkr they link to as an example, that showcases (almost) all hooks: http://plnkr.co/edit/?p=preview

That Plunker link doesn't work - I believe the right one is https://angular.io/resources/live-examples/lifecycle-hooks/ts/plnkr.html

@royaldark, yes, that's the one ! Thx :+1:

This can be seen as specific case/alias for asDirective https://github.com/angular/angular.js/pull/14080. Still have the issue with the hook.

I am using angular 1.5.11 with es6 and I am still facing with the issue of FormController not being available in components controller. I see this issue is closed, so what's the solution here?

@setry14 You can use the $postLink lifecycle hook added in 1.5.3.

Turns out I was calling my component (which has its own<form></form>) within the <form></form> of the calling template. That messed up the components <form></form>. Moving component form outside parents form made it dance! No need for $postLink, components FormController now just shows up on this.$scope.

Was this page helpful?
0 / 5 - 0 ratings