Skip to content
This repository has been archived by the owner on Dec 8, 2023. It is now read-only.

Require check fails for directive as transclude content #19

Closed
sasyomaru opened this issue Feb 27, 2015 · 14 comments
Closed

Require check fails for directive as transclude content #19

sasyomaru opened this issue Feb 27, 2015 · 14 comments

Comments

@sasyomaru
Copy link

I'm using ng-multi-transclude in a website and find an issue on the disconnection of transclude content and the context.
For example,

    <!doctype html>
    <html ng-app="myApp">
    <head>
      <script src="./angular.js"></script>
      <script src="./multi-transclude.js"></script>
      <script>
          angular.module('myApp', ['multi-transclude'])
                  .directive('myTemplate', function() {
                    return {
                        transclude: true,
                        template: [
                            '<div ng-multi-transclude-controller>',
                                '<h1>Some template A</h1>',
                                '<div ng-multi-transclude="some-block-a"></div>',
                                '<div ng-multi-transclude="another-block-a"></div>',
                            '</div>'].join('')
                    };
                  })
                  .directive('belowForm', function() {
                    return {
                      require: '^form',
                      template: '<div>This should be put in a form tag</div>',
                      link: function() { /* Trigger require checking */ }
                    };
                  });
      </script>
    </head>
    <body>
      <form>
          <my-template>
              <below-form name="some-block-a"></below-form>
              <below-form name="another-block-a"></below-form>
          </my-template>
          <div ng-multi-template="some-template">
              <below-form name="some-block-b"></below-form>
              <below-form name="another-block-b"></below-form>
          </div>
      </form>
      <script type="text/ng-template" id="some-template">
          <h1>Some template B</h1>
          <div ng-multi-transclude="some-block-b"></div>
          <div ng-multi-transclude="another-block-b"></div>
      </script>
    </body>
    </html>

When running the code, there will be an error "[$compile:ctreq] Controller 'form', required by directive 'belowForm', can't be found!" and the template is not filled correctly.
This is because the controller doesn't append the transclude content into its context until ctrl.transclude is called, but the link of directive happens in $transclude, which makes the content lost the context.

@sasyomaru
Copy link
Author

I've created a pull request to fix this problem (#20). Hopefully it will fix the issue. Would appreciate very much if you could have a look at it.

@zachsnow
Copy link
Owner

Thanks @sasyomaru! I believe this is the source of various the issues with controllers others have been having.

@rainboxx
Copy link
Contributor

rainboxx commented Mar 3, 2015

We're in need of a fix for this. Is the PR #20 the way a fix should be, @zachsnow?

At least it seems to work for the issue above (which is the same we have) :).

@zachsnow
Copy link
Owner

zachsnow commented Mar 3, 2015

@sasyomaru I played with this a little and it seems that we don't even need the hidden container, we can simply attach the transcluded content directly to the element, and then the link functions will move the content into the correct places.

@rainboxx it does indeed work, I just want to find the minimal solution possible (which this may well be).

@rainboxx
Copy link
Contributor

rainboxx commented Mar 3, 2015

@zachsnow I appreciate your investigation!

I found out that this PR will not fix all issues that we're having. Our directive using the multi-transclude also adds a form to the DOM. With a normal transclude we're able to access the form from within the transcluded content. Using the multi-transclude we cannot access that scope and therefor are unable to get our hands to the FormController.

@zachsnow
Copy link
Owner

zachsnow commented Mar 3, 2015

@rainboxx interesting, any chance you can sketch out more precisely what you mean?

@rainboxx
Copy link
Contributor

rainboxx commented Mar 3, 2015

I can try to make a jsfiddle tomorrow, I'm about to leave for bed now (UTC+1).

@zachsnow
Copy link
Owner

zachsnow commented Mar 3, 2015

@rainboxx thanks very much.

@zachsnow
Copy link
Owner

zachsnow commented Mar 4, 2015

@sasyomaru I suppose we could add ng-hide during the initial transclude and then remove it when moving the individual components to the correct place if there's a worry about flashing content perhaps? It seems it should be batched though.

@sasyomaru
Copy link
Author

The flashing content is also what I concerned most. But adding ng-hide may have conflict if the directive user already add ng-hide (for example, to show the template only under some condition).

@zachsnow
Copy link
Owner

zachsnow commented Mar 6, 2015

@sasyomaru you make a good point re: ng-hide. Ok, we'll use a nested container with ng-hide and remove the container when all of its content has been moved to the right position.

@zachsnow
Copy link
Owner

zachsnow commented Mar 7, 2015

It seems we should be able to get rid of this:

$scope.$on('$destroy', function(){
  if(toTransclude){
    toTransclude.remove();
    toTransclude = null;
  }
});

Because toTransclude stays in the DOM now, and so already be removed when the scope is destroyed, no?

@zachsnow
Copy link
Owner

zachsnow commented Mar 7, 2015

I've updated master to include these ideas.

@rainboxx
Copy link
Contributor

@zachsnow Sorry for the delay, kids got sick and we had to work on some different stuff first. I no longer think my issue is related to this so I opened another issue, #23. Thanks!

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

No branches or pull requests

3 participants