【问题标题】:Executing AngularJS function in a loop循环执行AngularJS函数
【发布时间】:2015-07-29 12:37:01
【问题描述】:

我正在做的是访问一个 API 并返回一个字符数组。每个角色的物品栏中都有一组物品。当我第一次得到信息时,它只给了我物品的 ID。然后,我必须使用该 ID 并进行另一个 API 调用以获取与该项目相关的信息,以便从中正确获取名称和统计信息。

<div class="gwapi_content row" ng-repeat="character in characters" ng-if="character.profession == 'Warrior'">

  <div class="character-header">
    <h3>{{character.name | uppercase}} <img src="img/{{character.profession}}_icon.png" alt=""></h3>
    <h5 class="subheader">{{character.race}} {{character.profession}}</h5>
  </div>

  <div class="column photo" style="background-image: url('../img/{{character.name}}.jpg')">
    <img src="img/{{character.profession}}_icon.png" alt="">
  </div>

  <div class="column info">
    <div class="panel-content">
      <ul>
        <li>NAME: {{character.name}}</li>
        <li>CLASS: {{character.profession}}</li>
        <li>
          LEVEL: {{character.level}}
        </li>
        <li>
          Race: {{character.race}}
        </li>
        <li>
          Gender: {{character.gender}}
        </li>
        <li>Birthday: {{character.created | date: 'MMMM dd, yyyy'}}</li>
        <li>Deaths: {{character.deaths}}</li>
      </ul>
    </div>
  </div>

  <div class="column equipment">
    <div class="panel-content">
      <ul class="">
        <li>
          <ul class="li equipment-list">
            <li ng-repeat="equip in character.equipment" ng-init="getEquipmentDetails(equip.id)">
              <span>
                {{equip.id}} {{details.name}}
              </span>
            </li>
          </ul>
        </li>
      </ul>
    </div>
  </div>

  <div class="clear"></div>
</div>

如您所见,我在获取项目列表的数组时调用了 item 函数: ng-repeat="equip in character.equipment" ng-init="getEquipmentDetails(equip.id)"

这就是我的问题所在。每当我使用 ID 进行此 API 调用时,所有名称都会被替换为它加载的最后一个名称。如下图所示。

我确定我在这部分做错了,但我以前没有遇到过这种情况,所以我不确定如何处理。我最终需要让每个角色获得各自的项目列表,以及项目各自的名称和统计信息。

这里是javascript:

$scope.getAccount = function(){

$http.get('https://api.guildwars2.com/v2/characters?access_token='+access_token+'&page=0')
.success(function(response, status, headers, config){
  // console.log(response);
  $scope.characters = response;
})
.error(function(data, status, headers, config) {
  console.log("Error retreiving data");
  // console.log(data + '\n' + status + '\n' + headers +'\n' + config);
});
};

$scope.getAccount();

$scope.getEquipmentDetails = function(id){


$http.get('https://api.guildwars2.com/v1/item_details.json?item_id=' + i)
.success(function(response, status, headers, config){

  $scope.details = response;

})
.error(function(response, status, headers, config){

  console.log('No info');

});

};

【问题讨论】:

  • 没有太多的角度开发,但我觉得您应该在控制器中执行该请求以获取所有设备详细信息。然后将其设置为您的范围,并在模板中对其进行迭代。
  • ngInit 唯一合适的用途是为 ngRepeat 的特殊属性设置别名,如下面的演示所示。除了这种情况,您应该使用控制器而不是 ngInit 来初始化作用域上的值。 docs.angularjs.org/api/ng/directive/ngInit

标签: javascript ajax angularjs loops


【解决方案1】:

问题的根源在于您正在为设备详细信息设置单个变量,因此单个变量的内容被绑定到模板。您可能会获得所有不同的详细数据,但最后完成的将始终是显示的,因为它将设置 $scope.details 的值并刷新模板,并且 {{details.name}} 的所有使用都会得到新值。

实际上它应该是这样工作的。

更好的方法是将仅装备传递给您的功能,然后将详细信息添加到您的功能中的装备。所以像:

ng-init="getEquipmentDetails(equip)"

然后将您的功能更改为:

$scope.getEquipmentDetails = function(equipment){

$http.get('https://api.guildwars2.com/v1/item_details.json?item_id=' + equipment.id)
.success(function(response, status, headers, config){
  equipment.details = response;
})
.error(function(response, status, headers, config){
  console.log('No info');
    });
}

然后更改您的模板以使用:

{{equip.details.name}}

这将修改 character.equipment 数组中的每个设备项,而不是控制器范围内的单个变量。

我也建议不要以这种方式使用 ng-init,这不是指令的真正意图。

【讨论】:

  • 感谢您的建议。我是一个新的 AngularJS 学习者,那么你会如何建议我避免以这种方式使用 ng-init?我应该在 API 中调用我的角色后立即调用吗?同样在尝试了代码之后,它得到了相同的响应:所有名称都被替换了。
  • 有几种方法可以解决这个问题,但最简单的方法就是执行 $scope.characters.forEach(function(character){ character.equipment.forEach(equip){ getEquipmentDetails(equip); } } 在你设置 $scope.characters 之后立即。
  • 我意识到您的代码有效。我在重写的时候犯了一个错误,但是我将采取这种方法并将其带入控制器以避免不良做法。
猜你喜欢
  • 1970-01-01
  • 2015-08-22
  • 1970-01-01
  • 1970-01-01
  • 2012-08-24
  • 2015-06-11
  • 1970-01-01
  • 2021-10-22
  • 1970-01-01
相关资源
最近更新 更多