AngularJS 绑定到模型时更新指令

AngularJS directive update when binding to model

目前我正在尝试向我的 angular 应用程序添加登录名。 angular 用户会话非常适合登录和注销。但我的指令是个麻烦制造者。

我添加了一个名为 access 的新 HTML 属性标记,它采用逗号分隔的用户角色列表。用户必须至少具有这些角色之一才能看到 html 元素。如果他有 none 个角色,他就看不到该元素(我不知道这是否是正确的方法,但我没有其他想法来隐藏没有导航项的用户使用权)。

<a class="navbar-brand" ng-href="/serverDebug" access="admin">Server Debug</a>

这里只有角色 admin 的用户可以看到菜单 link。
指令应该监视所有具有 access 属性的元素。

app.directive('access',
    function (AuthSharedService, UserSession) {
        return {
            /*
                    A = Attribute   = <div Doc></div>
                    C = Class       = <div class="Doc"></div>
                    E = Element     = <Doc data="book_data"></Doc>
                    M = coMment     = <!--directive:Doc -->
             */
            restrict: 'A',
            link: function (scope, element, attrs) {
                console.log("directive start");
                //scope.$watch('UserSession.user.roles', function (val) {
                    console.log("directive watcher change");
                    var roles = attrs.access.split(',');
                    if (roles.length > 0) {
                        if (AuthSharedService.isAuthorized(roles)) {
                            element.removeClass('hide');
                        } else {
                            element.addClass('hide');
                        }
                    }
                //});
            }
        };
    }
);

函数 AuthSharedService.isAuthorized 接受一组角色并将它们与 UserSession 进行比较。 (在 UserSession 中只存储了用户 ID、电子邮件和他的角色。)
如果其中一个角色在用户角色中,它返回 true,否则返回 false。这个功能很好用。我也在应用程序的其他地方使用它。

但似乎该指令只在 angular 开始时的 js 初始加载时触发一次。此时,AuthSharedService.isAuthorized 总是说 false 因为 UserSession 还没有加载。但这是在 angular 的 app.run 部分自动完成的。因此,仅几纳秒后,会话就会加载,用户就会登录。
但该指令不会触发第二次。所以我尝试使用一个观察者来每次触发指令,用户角色改变(开始时有 null,然后它将是一个数组,所以观察者应该工作)。但似乎我不擅长这样做。

我的错误是什么?我的观察者错了吗?还是我必须在指令之外使用观察者?但是我怎么调用指令呢?
感谢您的帮助。

使用观察器并让它调用一个函数:

app.directive('access',
    function (AuthSharedService, UserSession) {
        return {
            /*
                    A = Attribute   = <div Doc></div>
                    C = Class       = <div class="Doc"></div>
                    E = Element     = <Doc data="book_data"></Doc>
                    M = coMment     = <!--directive:Doc -->
             */
            restrict: 'A',
            link: function (scope, element, attrs) {
                console.log("directive start");
                var roles = attrs.access.split(',');
                function checkAuthorized() {
                    if (!roles.length) return false;
                    return AuthSharedService.isAuthorized(roles);
                }
                scope.$watch(checkAuthorized, function (val) {
                    console.log("directive watcher change ",val);
                    if (val) {
                        element.removeClass('hide');
                    } else {
                        element.addClass('hide');
                    }
                });
            }
        };
    }
);

Why can a watcher watch a function? I only use a watcher for variables and models

来自文档:

$watch(watchExpression, listener, [objectEquality])

watchExpression

Expression that is evaluated on each $digest cycle. A change in the return value triggers a call to the listener.

  • function(scope) called with current scope as a parameter.

  • string Evaluated as expression

— AngularJS $rootScope/$scope API Reference - $watch