0

我有一个简单的 Angular 应用程序,如下所示: html:

<body ng-app>
    <div class="content" ng-controller="LeaderboardCtrl">
        <div class="row" ng-repeat="fb_ranking in fb_rankings">
            <div class="rank cell">{{fb_ranking.rank}}</div>
            <div class="name cell">{{fb_ranking.name}}</div>
            <div class="score cell">{{fb_ranking.score}}</div>
        </div>
    </div>
</body>

和 JS:

function change_data(){
    some_data[0].rank = 99;
    var sc = angular.element(document.getElementById('overlay')).scope;
    sc.$apply(function(){
        sc.fb_rankings = some_data;
    });
}

var some_data = [
    {rank: 1, name: 'Boink a doodledo', score: 3000},
    {rank: 2, name: 'Someone else', score: 300},
    {rank: 3, name: 'Donkey', score: 30},
    {rank: 4, name: 'Booger landon', score: 20},
];
    
function LeaderboardCtrl($scope){
    $scope.fb_rankings = some_data;
}

一切都按预期工作。但是,我想some_data通过代码更新模型,而不是点击等事件。这是因为模型的更新是通过复杂的 Flash 和 DOM 交互来实现的。使用 ng-click 或其他基于事件的指令不是一个选项。

因此,为了更新模型,我使用了 change_data 函数来修改一个属性,然后尝试获取角度范围并使用 $apply 函数(根据网上找到的一堆教程和帖子。)。但是当我运行时change_data(),它会因以下错误而死: TypeError: Object function (a,d){v... etc.

我不知道这里有什么问题。或者错误甚至意味着什么。我在这里使用上面的代码有一个 jsfiddle:http: //jsfiddle.net/w2Ahr/1/

任何指向正确方向的指针都会很棒。

4

2 回答 2

1
function change_data(){
    some_data[0].rank = 99;
    var sc = angular.element("#overlay").scope();
    sc.$apply(function(){
        sc.fb_rankings = some_data;
    });

请注意,以这种方式修改 Angular 之外的范围是完全错误的,您应该只出于演示目的这样做,并且应该修改您的范围变量controller

于 2013-05-02T05:32:21.687 回答
0

直接调用 scope.$apply 可能会导致一些问题。使用包装器更安全:

// call this method to avoid '$apply already in progress'
$scope.updateScope = function (fn) {
    var phase = this.$root.$$phase;
    if (phase === '$apply' || phase === '$digest') {
        if (fn && (typeof(fn) === 'function')) {
            fn();
        }
    } else {
        this.$apply(fn);
    }
};

然后调用:

sc.updateScope(function(){
    sc.fb_rankings = some_data;
});
于 2014-05-02T10:04:04.407 回答