Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

FormController: attach to component controller? #13991

Closed
royaldark opened this issue Feb 10, 2016 · 13 comments · Fixed by #14302
Closed

FormController: attach to component controller? #13991

royaldark opened this issue Feb 10, 2016 · 13 comments · Fixed by #14302

Comments

@royaldark
Copy link

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?

@gkalpak
Copy link
Member

gkalpak commented Feb 10, 2016

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 ?

@jonricaurte
Copy link

@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.

@Narretz
Copy link
Contributor

Narretz commented Feb 10, 2016

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

@gkalpak
Copy link
Member

gkalpak commented Feb 10, 2016

(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.

@Narretz
Copy link
Contributor

Narretz commented Feb 10, 2016

Oh, yes, obviously. Thanks for correcting that.

@petebacondarwin
Copy link
Member

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

@gkalpak
Copy link
Member

gkalpak commented Feb 10, 2016

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

@royaldark
Copy link
Author

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

@gkalpak
Copy link
Member

gkalpak commented Feb 10, 2016

@royaldark, yes, that's the one ! Thx 👍

@drpicox
Copy link
Contributor

drpicox commented Mar 5, 2016

This can be seen as specific case/alias for asDirective #14080. Still have the issue with the hook.

petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Mar 22, 2016
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$afterViewInit` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
   they are waiting for their template to load asynchronously and their own compilation and linking has been
   suspended until that occurs.

Closes angular#14127
Closes angular#14030
Closes angular#14020
Closes angular#13991
petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Mar 23, 2016
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$afterViewInit` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
   they are waiting for their template to load asynchronously and their own compilation and linking has been
   suspended until that occurs.

Closes angular#14127
Closes angular#14030
Closes angular#14020
Closes angular#13991
Closes angular#14302
petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Mar 23, 2016
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$afterViewInit` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
   they are waiting for their template to load asynchronously and their own compilation and linking has been
   suspended until that occurs.

Closes angular#14127
Closes angular#14030
Closes angular#14020
Closes angular#13991
Closes angular#14302
petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Mar 23, 2016
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$afterViewInit` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
   they are waiting for their template to load asynchronously and their own compilation and linking has been
   suspended until that occurs.

Closes angular#14127
Closes angular#14030
Closes angular#14020
Closes angular#13991
Closes angular#14302
petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Mar 23, 2016
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$postLink` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
   they are waiting for their template to load asynchronously and their own compilation and linking has been
   suspended until that occurs.

Closes angular#14127
Closes angular#14030
Closes angular#14020
Closes angular#13991
Closes angular#14302
petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Mar 23, 2016
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$postLink` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
   they are waiting for their template to load asynchronously and their own compilation and linking has been
   suspended until that occurs.

Closes angular#14127
Closes angular#14030
Closes angular#14020
Closes angular#13991
Closes angular#14302
petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Mar 23, 2016
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$postLink` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
   they are waiting for their template to load asynchronously and their own compilation and linking has been
   suspended until that occurs.

Closes angular#14127
Closes angular#14030
Closes angular#14020
Closes angular#13991
Closes angular#14302
petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Mar 23, 2016
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$postLink` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
   they are waiting for their template to load asynchronously and their own compilation and linking has been
   suspended until that occurs.

Closes angular#14127
Closes angular#14030
Closes angular#14020
Closes angular#13991
Closes angular#14302
petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Mar 23, 2016
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$postLink` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
   they are waiting for their template to load asynchronously and their own compilation and linking has been
   suspended until that occurs.

Closes angular#14127
Closes angular#14030
Closes angular#14020
Closes angular#13991
Closes angular#14302
petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Mar 24, 2016
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$postLink` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
   they are waiting for their template to load asynchronously and their own compilation and linking has been
   suspended until that occurs.

Closes angular#14127
Closes angular#14030
Closes angular#14020
Closes angular#13991
Closes angular#14302
petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Mar 24, 2016
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$postLink` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
   they are waiting for their template to load asynchronously and their own compilation and linking has been
   suspended until that occurs.

Closes angular#14127
Closes angular#14030
Closes angular#14020
Closes angular#13991
Closes angular#14302
petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Mar 25, 2016
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$postLink` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
   they are waiting for their template to load asynchronously and their own compilation and linking has been
   suspended until that occurs.

Closes angular#14127
Closes angular#14030
Closes angular#14020
Closes angular#13991
Closes angular#14302
petebacondarwin added a commit that referenced this issue Mar 25, 2016
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$postLink` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
   they are waiting for their template to load asynchronously and their own compilation and linking has been
   suspended until that occurs.

Closes #14127
Closes #14030
Closes #14020
Closes #13991
Closes #14302
@sumeet-sethi
Copy link

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?

@royaldark
Copy link
Author

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

@sumeet-sethi
Copy link

sumeet-sethi commented Mar 31, 2017

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants