Angular.js在页面加载时缺少$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. 函数声明:(function() {...})
  2. 函数执行:()

因此,将2.的结果分配给$scope.forcast。它是一个完全静止的物体。

如果你想多次执行这个函数,可以这样声明:

 $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())"

毫无疑问,这不会比你以前更糟糕。如果由于--(例如)某个异步调用而仍有一些延迟,则应手动同步要一起更新的属性。

最新更新