angularjs - 在控制器范围内查看服务属性...从指令更改它们......没有更新?

时间:2014-03-31 17:38:02

标签: angularjs angularjs-directive angularjs-scope angularjs-service

假设我有一个非常简单的服务,上面有一些属性。如果我在控制器中使用该服务,将服务的属性放在作用域上,以便它们绑定到我的视图,并从控制器更新它们,它们将在视图中更新。这是我期望的行为。但是,如果从控制器范围之外的指令修改了相同服务的属性,则视图不会更新(除非某些事件触发了在控制器范围内更新的监视?)。显然我在这里缺少一些基本的东西,但搜索搜索搜索并没有让我得到答案。

以下是JSFiddle的示例。

app = angular.module('app', []);
// simple service to track application's logon status
app.factory('AuthService', function () {
    var status = {
        isLoggedIn: false
    };

    return {
        status: status,
        login: function () {
            status.isLoggedIn = true;
            console.log('user logged in');
        },
        loggedIn: function () {
            return status.isLoggedIn;
        },
        logout: function () {
            status.isLoggedIn = false;
            console.log('user logged out');
        }
    }
});

app.controller('AuthViewCtrl', function ($scope, AuthService) {
    // bind some service attributes, functions to the scope so that we can use them in our view
    $scope.loggedIn = AuthService.loggedIn;
    $scope.login = AuthService.login;
    $scope.logout = AuthService.logout;
    $scope.stat = AuthService.status;
});

// a simple directive to allow elements to log out of the app on click
app.directive('appLogout', function (AuthService) {
    return function (scope, element) {
        element.bind('click', function () {
            AuthService.logout();
        });
    }
});

// a simple directive to allow elements to log into the app on click
app.directive('appLogin', function (AuthService) {
    return function (scope, element) {
        element.bind('click', function () {
            AuthService.login();
        });
    }
});

随附的html:

<div ng-app="app">
    <div ng-controller="AuthViewCtrl">
        <strong>Are we logged in?</strong>
        <ul>
            <li>service func on scope: <strong>{{ loggedIn() }}</strong></li>
            <li>service prop on scope: <strong>{{ stat.isLoggedIn }}</strong></li>
        </ul>

        <button ng-click="login()">log in from controller scope</button>
        <button ng-click="logout()">log out from controller scope</button>
        <button ng-click="loggedIn()">call AuthService.loggedIn()</button>
    </div>

    <button app-login>log in from directive</button>
    <button app-logout>log out from directive</button>
</div>

启动时会退出该应用。如果您“从控制器登录[/ out]”,它调用发布到作用域的服务功能,则会在视图中立即更新监视的服务值。但是,如果您点击“从指令登录[/ out]”,则不会更新监视的服务值(如果您只是从作用域内调用AuthService.loggedIn(),它们将更新)。

所以,我想我的问题是,处理这个问题的最佳方法是什么?我在哪里观看服务价值时误入歧途?

谢谢, 亚当

1 个答案:

答案 0 :(得分:1)

问题是你在“角度”之外“服务”你的服务:

    element.bind('click', function () {
        AuthService.login();
    });

因此,您需要将呼叫包裹在$apply

    element.bind('click', function () {
        scope.$apply(function() {
            AuthService.login();
        });
    });

更新小提琴:http://jsfiddle.net/SAsBa/46/