angular的$ scope不更新?

时间:2016-03-09 17:39:59

标签: javascript angularjs angularjs-scope

我正在尝试根据用户的位置创建一个基本的天气应用程序,我使用javascript地理定位服务。关于位置和天气的一切都按预期工作 我的问题是当用户拒绝位置请求时,我想要做的是隐藏天气数据(我无法获取)并显示相应的消息。
HTML:

<body ng-app="weatherApp">
  <div class="container text-center" style="margin-top: 15vh" ng-controller="weatherCtrl">
    <h1>Local Weather App</h1>
    <h3>{{error}}</h3>
    <div class="row" ng-hide="showError">
      <div id="loc-col" class="col-xs-3 col-xs-offset-1">
        <h3>{{data.name}}</br>
        <small>{{data.sys.country}}</small></h3>
      </div>
      <div id="temp-col" class="col-xs-4">
        <h3>{{data.main.temp}} {{degree}}&deg;</h3>
      </div>
      <div id="weather-col" class="col-xs-3">
        <h3>{{data.weather[0].main}} </br><small>{{data.weather[0].description}}</small> </h3>
      </div>
      <div id="icon-col" class="col-xs-6 col-xs-offset-3">
        <img id="icon" class="img-responsive" ng-src="{{icon}}">
      </div>
    </div>
  </div>
</body>

错误消息应位于h1下面的<h3>

JS:

'use strict';
var app = angular.module('weatherApp', []);

app.factory('weatherFactory', ['$http', function($http){
  var weather = {};

  weather.getWeather = function(lat, lon){
    return $http.jsonp("http://api.openweathermap.org/data/2.5/weather?lat="+lat+"&lon="+lon+"&units=metric&callback=JSON_CALLBACK");
  };
  return weather;
}]);

app.controller('weatherCtrl', ['$scope', 'weatherFactory', '$http', function($scope, weatherFactory, $http){
  $scope.degree = "C";

  $scope.error = "";
  $scope.showError = false;

  var icons = { };

  function getWeatherFromPos(position){
    var lat = position.coords.latitude;
    var lon = position.coords.longitude;
    weatherFactory.getWeather(lat,lon).success(
            function(data){
              $scope.data = data;
              $scope.icon = icons[data.weather[0].icon];
            }
          ).error(function(error){
            setError(error);
          });
  }

  function setError(error){
    $scope.showError = true;
    $scope.error = error;
  }

  //THIS IS THE RELEVANT CODE:
  if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        function(position) {
          getWeatherFromPos(position);
        }, 
        function() {
          //EXECUTED UPON REJECTION
          setError("Geolocation service failed.");
        }
      );
    }
    else {
      setError("Your browser doesn't support geolocation.");
    }
}]);

当我打开控制器并执行以下操作时:

angular.element($(".row")).scope().error
"Geolocation service failed."

所以变量确实得到了更新,但是没有显示错误信息,也没有隐藏天气数据。

2 个答案:

答案 0 :(得分:1)

您的setError函数执行$digest个角度循环。 你可以这样做:

  function setError(error){
    $scope.showError = true;
    $scope.error = error;
    $scope.$apply();
  }

function setError(error){
    $scope.$apply(function () {
       $scope.showError = true;
       $scope.error = error;
   }
}

P.S。:它关注setError("Geolocation service failed.");setError("Your browser doesn't support geolocation.");

但对于setError(error),使用$apply是不行的,因为它已经在$digest循环内(不需要调用$apply方法)。请记住,只有在角度摘要循环之外进行了一些更改后才需要调用$apply。查看更多相关信息https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope#$ apply

答案 1 :(得分:0)

我想谢谢你错过了ng-bind:

public class BindingViewHolder<T extends ViewDataBinding> extends RecyclerView.ViewHolder {}

//it should be:

public class BindingViewHolder<T: ViewDataBinding> :
       RecyclerView.ViewHolder() {}