angularjs计算属性在模型更改后不更新

时间:2014-03-11 01:34:55

标签: angularjs

我在表中有一个简单的活动查看器,它列出了数据库中的活动及其状态(读取或未读取)。页面上有一个计数器,显示未读取的活动数量。每项活动都会根据条件为mark readmark unread提供选项。在更新model之后的某些原因,计算值在计数器上没有变化。

控制器

function Activity($scope, $http, $templateCache)
{
    $http.get('/activity/get').success(function(data, status)
    {
        $scope.activities = data;
    });

    $scope.totalActivities = function()
    {
        var count = 0;

        angular.forEach($scope.activities, function(activity)
        {
            count += activity.seen == 0 ? 1 : 0;
        });

        return count;
    }

    $scope.updateActivity = function(activity)
    {
        activity.seen = activity.seen == 0 ? 1 : 0;

        $http({
            method: 'PUT',
            url:    '/activity/' + activity.id,
            data:   { seen: activity.seen }
        })
        .success(function(data, status)
        {
            console.log(data);
        });
    }
}

计数器

<span class="badge badge-alert">{{ totalActivities() }}</span>

表格行+按钮

<tr ng-repeat="activity in activities" ng-class="{ 'activity-read': activity.seen == 1 }"> 
    <td>
        <button class="btn btn-default" ng-click="updateActivity(activity)"><span>@{{ 0 == activity.seen ? 'Mark Read' : 'Mark Unread' }}</span></button>
    </td>
</tr>

导航模板(单独的代码块)

<div class="account-details" ng-controller="Activity">
    @if (Sentry::hasAccess('admin'))
    <a href="{{ route('activity.index') }}" class="activity pull-left">
            <span class="badge badge-alert">@{{ totalActivities() }}</span>
        </a>
    @endif
</div>

首次加载时,计数器工作正常,但对模型的任何更新都需要页面刷新才能显示新计算。

2 个答案:

答案 0 :(得分:0)

有些东西告诉我,我们没有在这里看到代码的相关部分。

当我recreate your example使用$timeout代替$http时,一切正常运作:

var Activity = function($scope, $timeout) {
    console.log('creating controller');

    var fakeData = [
          {name: 'One',   seen: 0}, 
          {name: 'Two',   seen: 0},
          {name: 'Three', seen: 1},
          {name: 'Four',  seen: 0}
    ];

    $timeout(function () {
        $scope.activities = fakeData;
        console.log('data returned');
    }, 500);

    $scope.totalActivities = function () {
        var count = 0;

        angular.forEach($scope.activities, function (activity) {
            count += activity.seen === 0 ? 1 : 0;
        });

        return count;
    };

    $scope.updateActivity = function (activity) {
        activity.seen = activity.seen === 0 ? 1 : 0;

        var payload = {
            method: 'PUT',
            url: '/activity/' + activity.id,
            data: {
                seen: activity.seen
            }
        };

        $timeout(function () {
            console.log(payload);
        }, 200);
    };
};

jsFiddle Here:http://jsfiddle.net/jwcarroll/EBSB4/

答案 1 :(得分:0)

我还在计算属性和$ watch等方面挣扎了一段时间,无法想象它应该如此困难,然后我找到了这个解决方案:

What is the analog for Knockout's writable computed observable in AngularJS?

只需使用Javascript本身的强大功能来定义对象getter和setter。无需观看,非常简单。