Angular.js在页面加载时缺少$ scope update

时间:2013-12-04 10:05:52

标签: angularjs angularjs-scope

我有一个有趣的情况,我有一个天气应用程序,加载应用程序,我想让用户的最后位置,以及他们看到的最后一个预测,并显示,当应用程序去并获得更新的预测。

在我的控制器中,我构建了像这样的预测视图

function constructWeather(forecast){
        if(!forecast.data.list){
            $scope.loading='weather-error';
            return;
        }
        var today = forecast.data.list[0];
        console.log($scope.date);
        var date = $scope.date;
        $scope.print_date = $filter('date')(date,'EEEE, MMMM, d');
        $scope.print_time = $filter('date')(date,'h:mm a');
        $scope.weather = formatWeather(today,date,true);
        $scope.city =  $scope.position.name || forecast.data.city.name;

        $scope.forecast = (function(){
                            var day_list=[];
                            for(var d=1; d<6; d++){
                                var day_weather = formatForecast(forecast.data.list[d],date,false);
                                day_list.push(day_weather);
                            }
                            return day_list;
                        })();

        $scope.loading = 'weather-loaded';

    }

这在获取新的天气预报时工作正常,但是当我尝试重新加载旧的预测时,所有$ scope.print_date,$ scope.weather等工作正常,但只有$ scope.forecast在匿名函数中执行的那个,不显示。

我输出到控制台,我看到day_weather正在构建,但angular不会更新。

在模板中,它通过

加载
 &lt;div class="day" ng-repeat="day in forecast"&gt;
            &lt;div class="date"&gt;{{ day.print_date }}&lt;/div&gt;
            &lt;div class="long-day"&gt;{{ day.long_day }}&lt;/div&gt;
            &lt;div class="img {{weather.conditions | lowercase}}"&gt;&lt;/div&gt;
            &lt;div class="temps"&gt;
                &lt;span class="degrees"&gt;{{ day.weather.temps.max }}&lt;/span&gt;
                &lt;span class="min degrees"&gt;{{ day.weather.temps.min }}&lt;/span&gt;
            &lt;/div&gt;
        &lt;/div&gt;

当然,页面中没有添加div。

我尝试运行$scope.$apply,但它返回一个我已经处于摘要周期的错误。

还有另一种方法告诉Angular $ scope.forecast有新数据吗?

1 个答案:

答案 0 :(得分:3)

像你一样使用闭包,就像那样:

  1. 功能声明:(function() {...})
  2. 功能执行:()
  3. 因此,$scope.forcast分配了2.的结果。这是一个完全静态的对象。

    如果要多次执行此功能,请按以下方式声明:

     $scope.forecast = function(){ ... };
    

    并在你的标记中使用它:

    ng-repeat="day in forecast()"
    

    PLNKR显示了它的实际效果!


    <强>更新 $scope.forecast = (function(){...})()可以替换为:

    $scope.getForecast = function () {...};
    $scope.forecast = $scope.getForecast();
    

    然后在你的标记中你可以做类似的事情:

    ng-repeat="day in (forecast=getForecast())"
    

    当然,它不会比以前更糟糕。如果由于 - 例如 - 某些异步调用仍然存在一些延迟,则应手动同步要一起更新的属性。