从$ http.get调用更新Angular范围变量

时间:2016-04-10 13:42:38

标签: javascript angularjs

我对Angular很新,我试图弄清楚为什么范围变量在设置后不会更新。

我正在调用Node API来修复包含我的数据的json对象。除了将$ scope.profile设置为从API返回的数据外,一切似乎都能正常工作。

设定:

app.js

(function() {
  var app = angular.module("gamedin", []);


  app.controller('profileController', function($scope, $http, $timeout) {
    $scope.profile = {};

    $scope.getProfile = function() {
      var vanityUrl = $scope.text.substr($scope.text.lastIndexOf('/') + 1);

      $http.get('/steamid/' + vanityUrl)
      .then(function(data) {
        $http.get('/profile/' + data.data.response.steamid)
        .then(function(data) {
          console.log(data.data.response.players[0]); // Correct data
          $scope.profile = data.data.response.players[0]; // View isn't updated
        })
      })

      // Reset the input text
      $scope.text = "";
    }
  });

  ...

  app.directive('giHeader', function() {
    return {
      restrict: 'E',
      templateUrl: 'components/header/template.html'
    };
  })

  app.directive('giProfile', function() {
    return {
      restrict: 'E',
      templateUrl: 'components/profile/template.html'
    }
  })

})();

部件/报头/ template.html

<header>
  <div class="header-content" ng-controller="profileController">
    <div class="col-md-3"></div>

    <div class="col-md-6">
      <div class="header-content-inner">
        <input ng-model="text" ng-keyup="$event.keyCode == 13 && getProfile()" class="form-control" type="text" placeholder="Enter Steam URL">
      </div>
      <p>e.g., http://steamcommunity.com/id/verydankprofilelink</p>
    </div>

    <div class="col-md-3"></div>
  </div>
</header>

组件/简档/ template.html

<div class="container">
  <div ng-controller="profileController">
    <h3> 
      <strong>Username: {{ profile.personaname }}</strong>
    </h3>
    <p> SteamID: {{ profile.steamid }}</p>
  </div>
</div>

的index.html

<!doctype html>
<html ng-app="gamedin">
<head>
  ...
</head>

<body>

  ...

  <gi-header></gi-header>

  <gi-profile></gi-profile>

  ...

</body>
</html>

我已尝试将其包装在$ scope中。$ apply,就像这样

$scope.$apply(function () {
  $scope.profile = data.data.response.players[0];
});

...导致Error: [$rootScope:inprog]

然后我试了

$timeout(function () {
  $scope.profile = data.data.response.players[0];
}, 0);

$scope.$evalAsync(function() { 
  $scope.profile = data.data.response.players[0]; 
});

...虽然没有抛出任何错误,但视图仍然没有更新。

我意识到我可能没有正确理解角度的某些方面,所以请赐教!

2 个答案:

答案 0 :(得分:1)

问题是您有2个profileController个实例,每个指令模板中有一个实例。它们应该共享同一个实例,因为现在发生的是一个实例更新其范围内的profile变量,另一个实例不知道。即,标题模板的profileController实例正在执行调用,您希望在配置文件模板上看到更改。

您需要重组。我建议在使用该指令的页面中使用控制器,并在两个指令中共享配置文件对象:

  <gi-header profile="profile"></gi-header>

  <gi-profile profile="profile"></gi-profile>

在每个指令中:

return {
  restrict: 'E',
  scope: {
     profile: '='
  },
  templateUrl: 'components/header/template.html'
};

更一般地说 - 如果你想在指令中使用控制器,你应该使用指令&#34;控制器&#34;属性。

答案 1 :(得分:0)

请尝试使用此方法:

$http.get('/steamid/' + vanityUrl)
  .then(function(data) {
    return $http.get('/profile/' + data.data.response.steamid).then(function(data) { 
      return data;
    });
  })
  .then(function(data) {
     $scope.profile = data.data.response.players[0]; // View isn't updated
  })

使用两个分辨率而不是一个,然后从第二个分辨率更新范围。