2017-07-04 36 views
2

控制器中的我的分配$scope.getForecastByLocation未傳遞到控制器。目前city被指定爲像「伯克利」這樣的隨機城市,並且該城市被傳遞到工廠數據。但這個想法是,當用戶在輸入中鍵入一個新的城市時,它接受輸入並向Data工廠發送一個新的城市參數。控制器中的分配未傳遞到服務

我一直在做console.logs,我可以看到按鈕正在工作,但調用Data.getApps($scope.inputcity);不工作,因此城市總是在「伯克利」。

任何人都可以找出爲什麼我不能發送一個新的城市到數據工廠嗎?謝謝!

的index.html

<input ng-model="city"> 
    </md-input-container> 
    <md-button class="md-raised" ng-click="getForecastByLocation(city)">SUBMIT</md-button> 

controller.js

var app = angular.module('weatherApp.controllers', []) 

    var city = 'Berkeley'; 

    app.controller('weatherCtrl', ['$scope','Data', 

     function($scope, Data) { 
     $scope.getForecastByLocation = function(city) { 
       $scope.inputcity = city; 
       console.log($scope.inputcity); 
       Data.getApps($scope.inputcity).then(function(data){ 
        $scope.data = data; 
        $scope.name = data.name; 
        console.log($scope.data); //object shows "Berkeley" 
        console.log($scope.name); 
       });//initiate Data.getApps by passing in a new city 
     } 
     Data.getApps(city).then(function(data) { 
      $scope.data = data; 

      var vm = $scope; 

      vm.description = data.weather[0].description; 
      vm.speed = (2.237 * data.wind.speed).toFixed(1) + " mph"; 
      vm.name = data.name; 
      vm.humidity = data.main.humidity + " %"; 
      vm.temp = data.main.temp; 
      vm.fTemp = (vm.temp * (9/5) - 459.67).toFixed(1) + " °F"; 

     },function(res) { 
      if(res.status === 500) { 
       // server error, alert user somehow 
      } else { 
       // probably deal with these errors differently 
      } 
     } 

     ); // end of function 

    }])//end of controller 

service.js

app.factory('Data', function($http, $q) { 

    var data = [], 
     lastRequestFailed = true, 
     promise; 
    return { 
     getApps: function(city) { 
     if(!promise || lastRequestFailed) { 
      // $http returns a promise, so we don't need to create one with $q 

      promise = $http.get('http://api.openweathermap.org/data/2.5/weather?',{ 
       params: { 
       q: city, 
       } 
      }) 
      .then(function(res) { 
       lastRequestFailed = false; 
       data = res.data; 
       return data; 
      }, function(res) { 
       return $q.reject(res); 
      }); 
     } 
     return promise; 
     } 
    } 
}); 

編輯:

我修改我的控制器代碼一點從其他人的建議和它rrently看起來像這樣。工廠是一樣的,我已經刪除了HTML中的參數。

app.controller('weatherCtrl', ['$scope','Data', 

    function($scope, Data) { 
$scope.city = 'Berkeley'; 

$scope.getForecastByLocation = function() { 
       console.log($scope.city); //making sure I can read the input 
       console.log('this is your input ' + $scope.city); 
       Data.getApps($scope.city).then(function(data){ 
       console.log('this is your output ' + $scope.city); //should say "This is your output "tracy", but it still reads at "Berkeley" 

        $scope.data = data; 
        $scope.name = data.name; 
        console.log($scope.data); //object shows "Berkeley" 
        console.log($scope.name); 
       });//initiate Data.getApps by passing in a new city 
     } 

enter image description here

+0

ngclick => ngclick? – gxvv

+0

哦,這是一個複製和粘貼錯誤。在我的實際代碼中,它實際上是ng-click。 – hiswendy

+0

通過'$ scope.city'獲取城市值,而不是通過** city **參數。 – gxvv

回答

2

var app = angular.module('weatherApp.controllers', []) 
 

 
    var city = 'Berkeley'; 
 

 
    app.controller('weatherCtrl', ['$scope','Data', 
 

 
     function($scope, Data) { 
 
     $scope.getForecastByLocation = function() { 
 
       $scope.inputcity = $scope.city; 
 
       console.log($scope.inputcity); 
 
       Data.getApps($scope.inputcity).then(function(data){ 
 
        $scope.data = data; 
 
        $scope.name = data.name; 
 
        console.log($scope.data); //object shows "Berkeley" 
 
        console.log($scope.name); 
 
       });//initiate Data.getApps by passing in a new city 
 
     } 
 
     Data.getApps(city).then(function(data) { 
 
      $scope.data = data; 
 

 
      var vm = $scope; 
 

 
      vm.description = data.weather[0].description; 
 
      vm.speed = (2.237 * data.wind.speed).toFixed(1) + " mph"; 
 
      vm.name = data.name; 
 
      vm.humidity = data.main.humidity + " %"; 
 
      vm.temp = data.main.temp; 
 
      vm.fTemp = (vm.temp * (9/5) - 459.67).toFixed(1) + " °F"; 
 

 
     },function(res) { 
 
      if(res.status === 500) { 
 
       // server error, alert user somehow 
 
      } else { 
 
       // probably deal with these errors differently 
 
      } 
 
     } 
 

 
     ); // end of function 
 

 
    }]); 
 
    app.factory('Data', function($http, $q) { 
 

 
    var data = [], 
 
     lastRequestFailed = true, 
 
     promise; 
 
    return { 
 
     getApps: function(city) { 
 
     if(!promise || lastRequestFailed) { 
 
      // $http returns a promise, so we don't need to create one with $q 
 

 
      promise = $http.get('http://api.openweathermap.org/data/2.5/weather?',{ 
 
       params: { 
 
       q: city, 
 
       } 
 
      }) 
 
      .then(function(res) { 
 
       lastRequestFailed = false; 
 
       data = res.data; 
 
       promise = false; // reset the promise value. 
 
       return data; 
 
      }, function(res) { 
 
       return $q.reject(res); 
 
      }); 
 
     } 
 
     return promise; 
 
     } 
 
    } 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="weatherApp.controllers"> 
 
    <div ng-controller="weatherCtrl"> 
 
     <input ng-model="city"> 
 
     <md-button class="md-raised" ng-click="getForecastByLocation()">SUBMIT</md-button> 
 
    </div> 
 
</div>

+0

對不起,但我很難理解'$ scope.inputcity = $ scope.city;'。如果我理解正確,輸入現在將被存儲爲'$ scope.inputcity',這就是我們傳遞給Data factory的參數。將$ scope.city設置爲什麼要點?另外,我嘗試了你的方法,但是對象仍然是伯克利:( – hiswendy

+0

API不適合我,原因是你沒有重置'promise',這個承諾總是第一個請求的承諾。 – gxvv

+0

我拿走了api密鑰,我知道這就是爲什麼它沒有運行,我應該把它放進去嗎?我怎樣才能重置'promise'? – hiswendy

0

我相信你的控制器嘗試指派$scope.inputcityvar city = 'Berkeley的值,而不是將其分配給函數的參數city的價值。最好的做法是避免對從函數的作用域和函數的參數可訪問的變量使用相同的名稱。

爲什麼不直接在控制器中直接訪問$scope.city而不是將city作爲參數傳遞給ng-click="getForecastByLocation(city)"

你的函數看起來是這樣的:

$scope.getForecastByLocation = function() { 
      console.log($scope.city); 
      Data.getApps($scope.city).then(function(data){ 
       $scope.data = data; 
       $scope.name = data.name; 
       console.log($scope.data); //object shows "Berkeley" 
       console.log($scope.name); 
      }); 
    } 
+0

對不起,如果這是一個基本的問題,但我只是想真正澄清我對angularjs的理解。所以如果是這樣的話,那麼在HTML中,沒有參數只是'ng-click = getForecastByLocation()'對吧?那麼在工廠裏,它的參數也是'$ scope.city'嗎? – hiswendy

+0

正確,您不需要HTML中的'getForecastByLocation()'參數。我建議在你的控制器中設置一個默認值,比如'$ scope.city ='Berkeley';',這樣你就不再有一個'city'變量導致你的函數參數名稱混淆。我不認爲你需要改變工廠,特別是因爲它不訪問'$ scope'。 –

+0

不幸的是,儘管我試圖改變這個城市,但我仍然嘗試了你的方法,我仍然把輸出作爲「伯克利」。如果你看看我上面的編輯,你可以看到我輸入了「東京」,它將東京視爲'$ scope.city',但由於某種原因,它並沒有作爲工廠中的參數傳遞。你有什麼想法,爲什麼? – hiswendy

相關問題