-
Notifications
You must be signed in to change notification settings - Fork 27.5k
Directive could not find parent directive's controller on AngularJS 1.2.0 when replace property is set to 'true' #4935
Comments
Thanks for reporting this. This problem was added by this commit in 1.2.0-rc3: 78656fe Reason:
Possible solutions:
|
@IgorMinar What do you think about this? |
jQuery added this check by this issue: http://bugs.jquery.com/ticket/8335. So the problem is that jQuery is not cleaning up comment nodes as it just a element.getElementsByTagName('') / querySelectorAll('') for finding the children to clean up when |
A simpler case for this: See this plunk: http://plnkr.co/edit/iyUvYEjU8U52Quy94UKm?p=preview |
Actually patching / fixing |
Btw, I don't think this was introduced by 78656fe as that commit is part of 1.0 |
I see, it was not issue before 1.2, because ng-include did not use to use transclusion before (which implies using a comment node). |
Here's updated plunker with a workaround (see app.js:14-16) http://plnkr.co/edit/evNrjfkEmQx5iutkJ7Ub?p=preview Discussed with Tobias and he's gonna make a fix (basically the workaround above) that we could put in 1.2.1. Long term I believe we should get rid off this issue completely by not putting stuff on comment elements. I think at the time when we only have the comment placeholder, there's no reason for anybody to ask for the controller (neither there is any reason for the controller to be instantiated). Also, a transclusion can be applied multiple times (eg. ng-repeat), in which case we need to use a different controller per transclusion instance (clone) anyway - having "a comment node controller" is useless (basically another bug, that ng-repeat would currently give every instance the same "comment node controller"). |
Here is a more practical example: |
See this plunk: http://plnkr.co/edit/HdKTOzYVS6Odx2FWczBj?p=preview |
Btw: Same is true for We are cloning the element using a transclude, but as the directive has The solution to the initial problem looks like this:
I don't think it's possible to move this specific into the compiler for a generic solution, as there seems to be no possibility how the
The example above is able to solve this by using the javascript closure. A general solution could be to create a new transclude function for every call to the link function of a directive. Such a transclude function would then have access to the controllers of the linking phase and also the cloned element. We already have something like this: So in the end we could just extend |
Thanks for looking into this issue but I'm still a little bit confused. Unfortunately my understanding about transclude-related the angular internals is not that good yet. If I followed your discussion correctly the workarounds you mentioned needs to be applied to the directive that uses the transclude option. So in my initial scenario it would have to be applied to the ng-include directive but not to the main directive, correct? |
…s from child elements. Additional API (backwards compatible) - Injects `$transclude` (see directive controllers) as 5th argument to directive link functions. - `$transclude` takes an optional scope as first parameter that overrides the bound scope. Deprecations: - `transclude` parameter of directive compile functions (use the new parameter for link functions instead). Refactorings: - Don't use comment node to temporarily store controllers - `ngIf`, `ngRepeat`, ... now all use `$transclude` Closes angular#4935.
…s from child elements. Additional API (backwards compatible) - Injects `$transclude` (see directive controllers) as 5th argument to directive link functions. - `$transclude` takes an optional scope as first parameter that overrides the bound scope. Deprecations: - `transclude` parameter of directive compile functions (use the new parameter for link functions instead). Refactorings: - Don't use comment node to temporarily store controllers - `ngIf`, `ngRepeat`, ... now all use `$transclude` Closes angular#4935.
Hi, Please note that you have to wait until the ngInclude is loaded to change the DOM. Also, ngInclude will create a new element, so you can't just use the |
Ah, I didn't know that 1.2.1 will be release so soon, that's why I asked for an workaround. Great work! |
…hildren Additional API (backwards compatible) - Injects `$transclude` (see directive controllers) as 5th argument to directive link functions. - `$transclude` takes an optional scope as first parameter that overrides the bound scope. Deprecations: - `transclude` parameter of directive compile functions (use the new parameter for link functions instead). Refactorings: - Don't use comment node to temporarily store controllers - `ngIf`, `ngRepeat`, ... now all use `$transclude` Closes angular#4935.
…hildren Additional API (backwards compatible) - Injects `$transclude` (see directive controllers) as 5th argument to directive link functions. - `$transclude` takes an optional scope as first parameter that overrides the bound scope. Deprecations: - `transclude` parameter of directive compile functions (use the new parameter for link functions instead). Refactorings: - Don't use comment node to temporarily store controllers - `ngIf`, `ngRepeat`, ... now all use `$transclude` Closes angular#4935.
Hello
While upgrading an application from AngularJS version 1.1.5 to 1.2.0 I ran into some issues which are related to inter-directive communication, done via directive's controller. In the application there's a parent directive and a child directive. At a certain point the child directive has to call a method of its parent directive's controller. Therefore the parent directive is marked as required in the child directive. One specialty about this scenario is that the parent directive uses a template which contains an ng-include directive to dynamically load a template which uses the child directive.
When running on version 1.2.0 the child directive throws an error with the following message: "Controller 'xxx', required by directive 'yyy', can't be found!"
After debugging and some more investigation I think the problem is related to the ng-include directive, but I'm not 100% sure why it doesn't work any more with version 1.2.0.
I managed to reproduce the problem on Plunker : http://plnkr.co/edit/COAkdNCYuMhpaHsWFopx
In the example I currently use version 1.2.0 so it won't work but you can easily switch to version 1.1.5 to see how it should work.
The error only happens when the 'replace' variabel is set to 'true'. If it is set to 'false' everything works as expected.
The text was updated successfully, but these errors were encountered: