Skip to content
This repository has been archived by the owner on Oct 2, 2019. It is now read-only.

Fixes transclusion on angular v1.2.18+ #91

Merged
merged 2 commits into from
Jul 3, 2014
Merged

Fixes transclusion on angular v1.2.18+ #91

merged 2 commits into from
Jul 3, 2014

Conversation

dimirc
Copy link
Contributor

@dimirc dimirc commented Jun 28, 2014

The choices template needed ng-tranclude, but it won't work anymore the same way since angular changed/corrected the way the transclusion and the scope bound.

The alternative could be to use a new class ui-select-choices-row-inner instead of ng-transclude to mark the location where we want to put the transcluded content by calling the transcludeFn from link function.

Working plunker

Fixes: #85
Fixes: #80

@dimirc dimirc changed the title fix(choices): change the way transclusion is done for choices. Compatibl... Fixes transclusion on angular v1.2.18+ Jun 28, 2014
@dimirc dimirc added this to the 0.3.x milestone Jun 30, 2014
@petebacondarwin
Copy link
Member

+1 for using some other marker to find the injection point.

You should not be using transclusion at all here as the content of the element containing the ui-select directive is used as a template not a transclusion. Instead, make the directive terminal and then do the manipulation directly on the element where you wish to inject as part of the compile function. Then as you do, call $compile on the contents of the directive's element.

@dimirc
Copy link
Contributor Author

dimirc commented Jul 1, 2014

@petebacondarwin at the compile function of the uiSelect directive, what I'd get from the tElement is the template of this directive and not what the user added on-the-fly on the directive, that's why I'm using transclusion, to get the content of what the user wrote inside the directive.

I created this plunker with the compile function added to the uiSelect directive and a console.log of the tElement

Let me know your comments please

@petebacondarwin
Copy link
Member

@dimirc - yes, if you provide a template I think it gets inserted before you get to the compile function. In that case you need to terminate the directive and do the template bit yourself.
I am confident though that using transclusion and a second directive - e.g. inject as below is a good workaround:

myApp.directive( 'inject', function() {
    return {
        link: function( $scope, $element, $attrs, controller, $transclude ) {
            if ( !$transclude ) {
                throw minErr( 'ngTransclude' )( 'orphan',
                    'Illegal use of ngTransclude directive in the template! ' +
                    'No parent directive that requires a transclusion found. ' +
                    'Element: {0}',
                    startingTag( $element ));
            }

            $transclude( $scope, function( clone ) {
                $element.empty();
                $element.append( clone );
            });
        }
    };
}); 

@dimirc
Copy link
Contributor Author

dimirc commented Jul 1, 2014

@petebacondarwin I like the idea of using a directive as marker of injection point.

Take a look at this commit basically I'm doing a directive very simillar to ngTransclude but also with the option to specify a class so that we only inject part of the transcluded content in that specific marker and not all. That's needed on the select template where we have 2 injection points.

I only found one problem, and is that an exception is shown complaining about a parent controller not found even when the directive is working correctly.

You could check this at console from this plunker. Maybe this has to do with how internally controllers are bound when using transcludeFn but I have no idea what to do here.

PD: there are some failing test that I could check later, first I want to check better this alternative

@dimirc
Copy link
Contributor Author

dimirc commented Jul 2, 2014

I still don't find a way to prevent those exceptions. They might be caused because we're calling the transcludeFn twice for same content since we only need part of the content for each marker. If I only use the directive once (for all transcluded content or part of it) it works correctly without any exception, but when I use the directive as a sibling then this problem shows.

I found a related directive that could help, but I don't think the effort will be worth and we could keep the marker classes for now

@petebacondarwin
Copy link
Member

@dimirc I am afraid you are stretching the limits of what can be achieved with transclusion and templates. You may well need to just make the uiSelect directive terminal and then deal with all this manually.

dimirc added a commit that referenced this pull request Jul 3, 2014
Fixes transclusion on angular v1.2.18+
@dimirc dimirc merged commit 9614b86 into master Jul 3, 2014
@dimirc dimirc deleted the fix-transclude branch July 3, 2014 01:59
@dimirc
Copy link
Contributor Author

dimirc commented Jul 3, 2014

We'll keep using classes to mark injection points for now

@alkrauss48
Copy link

For anyone else having this issue even though it was fixed, check your Angular version. I was running 1.2.16, and updating to 1.2.26 solved this issue.

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

Successfully merging this pull request may close these issues.

ui-select breaks with angular js v1.3.0 No longer works with 1.3.0-beta11
3 participants