AngularJS : Directive transcluded scope lost

浪子不回头ぞ 提交于 2019-12-06 03:30:17
Vadim

Both ng-if and ng-transclude directives perform transclusion in your directive. In this case build-in transclude mechanism does not work fine and you should implement ngIf of yourself to make it work as expected:

JavaScript

app.directive('requiresAuthorization', function () {
    return {
        template: '<div ng-transclude></div>',
        restrict: 'E',
        transclude: true,
        scope: {
            role: '@'
        },
        controller: function ($scope) {
            $scope.iAmInRole = true;
        },
        link: function(scope, element, attr, ctrl, transcludeFn) {
            transcludeFn(function(clone) { // <= override default transclude
                element.empty();
                if(scope.iAmInRole) { // <= implement ngIf by yourself
                  element.append(clone);
                }
            });
        }
    };
});

Plunker: http://plnkr.co/edit/lNIPoJg786O0gVOoro4z?p=preview

If ng-show is an option for you to use instead of ng-if it may be a very simple workaround as well. The only side effect is that hidden data will be presented in the DOM and hidden using CSS .ng-hide {display: none !important;}.

JSFiddle: http://jsfiddle.net/WfgXH/3/

This post may also be useful for you since it describes the similar issue: https://stackoverflow.com/a/22886515/1580941

Once you define the scope property in your directive, it becomes an isolated scope. With no access to the outside (well, in a way, the only way is ugly and should be avoided), except to the stuff you pass into it via the scope property.

You'll need to either pass them into the directive: updated your jsfiddle

<requires-authorization role='Admin' data-auth-value='authValue' data-unauth-value='unAuthValue'>
  <div>Inside directive. For Admin eyes only</div>
  <p>{{authValue}}</p>
</requires-authorization>

// your directive scope
scope: {
  role: '@',
  authValue: '=',
  unauthValue: '='
}

Or create a service/factory to act as a middle man to communicate.

You use ng-if. It does transclusion as well, unfortunately using a child scope of it's own scope, which in turn is the isolate scope.

Below are the screenshots from Batarang. The first is your code with ng-if. 4 is the isolate scope, 6 the transcluded content.

The same without ng-if. The transcluded content is now 5 and a sibling of the isolate scope and, more importantly, child of the controller's scope.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!