让 Angular 检测 $scope 的变化

Getting Angular to detect change in $scope

我正在编写我的第一个 AngularJS 应用程序,我正在尝试获取指令以在从服务接收到的数组发生更改时更新其视图。

我的指令是这样的:

angular.module('Aristotle').directive('ariNotificationCenter', function (Notifications) {
    return {
        replace: true,
        restrict: 'E',
        templateUrl: 'partials/ariNotificationCenter.html',
        controller: function ($scope) {
            $scope.notifications = Notifications.getNotifications();

            $scope.countUnread = function () {
                return Notifications.countUnread();
            };
        }
    };
});

部分很简单:

<p>Unread count: {{countUnread()}}</p>

虽然我的 Notifications 服务看起来像这样:

function Notification (text, link) {
    this.text = text;
    this.link = link;
    this.read = false;
}

var Notifications = {
    _notifications: [],

    getNotifications: function () {
        return this._notifications;
    },

    countUnread: function () {
        var unreadCount = 0;

        $.each(this._notifications, function (i, notification) {
            !notification.read && ++unreadCount;
        });

        return unreadCount;
    },

    addNotification: function (notification) {
        this._notifications.push(notification);
    }
};

// Simulate notifications being periodically added
setInterval(function () {
    Notifications.addNotification(new Notification(
        'Something happened!',
        '/#/somewhere',
        Math.random() > 0.5
    ));
}, 2000);

angular.module('Aristotle').factory('Notifications', function () {
    return Notifications;
});

getNotifications 函数 returns 对数组的引用,它在调用 addNotification 时被 setInterval 设置更改。然而,让视图更新的唯一方法是 运行 $scope.$apply(),这很糟糕,因为它删除了 Angular.

的所有自动方面。

我做错了什么?

谢谢。

我还不是 Angular 方面的专家,但看起来您的问题可能是部分问题。

<p>Unread count: {{countUnread()}}</p>

我认为您不能绑定到函数的结果。如果这个可行,我相信它只会计算一次值,然后就完成了,这似乎是你写的问题。

相反,我认为您应该创建一个同名变量:

$scope.countUnread = 0;

然后用函数更新控制器中的值。

然后,在您的部分中,删除括号。

<p>Unread count: {{countUnread}}</p>

只要$scope.countUnread确实在controller中更新了,变化应该会反映在partial中。

附带说明一下,如果您采用这种方法,我建议重命名变量或函数,因为这可能会导致问题,或者至少会造成混淆。

我认为您的代码唯一的问题是您使用 setInterval 来更新模型数据,而不是 Angular 内置服务 $interval。用

替换对 setInterval 的调用
$interval(function () {
    Notifications.addNotification(new Notification(
        'Something happened!',
        '/#/somewhere',
        Math.random() > 0.5
    ));
}, 2000);

无需调用 $scope.$apply 也能正常工作。还要记得在工厂实现 Notifications.

中注入 $interval 服务

angular.module('Aristotle').factory('Notifications', function ($interval) {

$interval 内部调用 $scope.$apply.