0

我正在編寫我的第一個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函數返回引用數組,由更改調用addNotification時設置爲。但是,獲取視圖更新的唯一方法是運行$scope.$apply(),這很糟糕,因爲這會刪除Angular的所有自動操作方面。

我在做什麼錯?

謝謝。

回答

2

我相信你的代碼唯一的問題是你使用setInterval來更新模型數據,而不是Angular內置服務$ interval。與

$interval(function() { 
    Notifications.addNotification(new Notification(
     'Something happened!', 
     '/#/somewhere', 
     Math.random() > 0.5 
    )); 
}, 2000); 

更換電話給setInterval它應該沒有你打電話$scope.$apply工作。還請記住在工廠實施Notifications中注入$interval服務。

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

$interval內部調用$scope.$apply

+0

我剛剛從這篇文章發現同一時間:http://jimhoskins.com/2012/12/17/angularjs-and-apply.html。非常感謝,Angular知道該範圍已被修改的唯一方法是讓它知道偵聽更新。 – 2015-04-06 05:31:20

+0

是的,這是一篇優秀的文章。角度需要知道模型何時改變。它觀察一些觸發器來確定。這些觸發器包括遠程請求,間隔和超時請求,鍵盤和鼠標事件。 – Chandermani 2015-04-06 05:34:15

1

我不是Angular的專家,但它看起來像您的問題可能在部分。

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

我不認爲你可以綁定到函數的結果。如果這樣做,我相信它只會計算一次價值,然後就結束了,這似乎是你寫的問題。

相反,我相信你應該同名作變量:

$scope.countUnread = 0; 

,然後更新與功能控制器中的值。

然後,在您的部分中,刪除括號。

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

只要$scope.countUnread在控制器的確更新時,變化應該反映在所述部分。作爲一個方面說明,如果你採取這種方法,我建議重命名變量或函數,因爲這可能會導致問題,或至少是混亂。

+0

'countUnread'是一個函數,它是一個附加到'$ scope'(在我的第一個代碼塊中定義的問題)的方法。 – 2015-04-06 05:19:19

+0

在發佈之後,我再次查看了代碼示例,並看到了該示例。我剛剛徹底改變了我的答案,因爲我認爲現在是正確的方法。對於那個很抱歉。 – Chad 2015-04-06 05:20:21

+0

好的,所以其他控制器(或潛在的後端)可能會調用Notifications服務上的方法來添加通知。如果我只是在控制器中存儲一個數字,我該如何做到這一點,以便當另一個單獨的控制器向Notifications服務推送通知時,該指令將重新計算未讀數量? – 2015-04-06 05:23:41