【问题标题】:AngularJS - Resolved data doesn't refresh in nested state componentsAngularJS - 解析的数据不会在嵌套状态组件中刷新
【发布时间】:2017-05-23 02:24:15
【问题描述】:

我正在使用 AngularJS 1.5、ui-router 和 angular-resource,我正在开发一个基于组件的应用程序。我有一个父状态,用于获取和更新数据,该数据通过父状态解析器绑定到多个子状态。

当我在父组件控制器中手动更改数据时(例如vm.town.x = 666),一切正常,并且更改在子状态组件中可见。但是,当我根据其余服务的响应(使用 angular-resource)更改父组件控制器中的数据时,数据更改仅在父状态组件中可见。

状态定义:

.state('town', {
  url: '/my-towns/:townId/',
  component: 'town',
  bindings: {
    town: 'townData'
  },
  resolve: {
    townData: function(Town, $stateParams) {
      return Town.get({
        townId: $stateParams.townId
      });
    }
  }
})

.state('town.detail', {
  url: 'detail',
  component: 'townDetail',
  bindings: {
    town: 'townData'
  }
})

父(镇)组件控制器定义:

function TownCmpController(TownServices,Town,BuildingUpgradeRest) {
  var vm = this;
  this.upgradeBuilding = function(data) {
     vm.town = BuildingUpgradeRest.update({townId:  vm.town.TownId,buildingId: data.building.BuildingId});
}

休息服务定义:

.factory('BuildingUpgradeRest',function($resource){
    return   $resource('api/public/v1/myaccount/towns/:townId/buildings/:buildingId/upgrade', {townId:'@townId', buildingId: '@buildingId'}, {
    'update': {
      method: 'PUT'
      }
    });
  })

'town' 对象绑定在两个组件中是相同的

bindings: {
    town: '<'
  }

两个服务都返回相同的对象类型并且都可以工作。

【问题讨论】:

  • 这最初是有效的,因为您在过渡期间解决了城镇。当它成功时,两个组件都将解析值town 绑定到它们的输入。当您更改 vm.town 的值时,您将覆盖父控制器上的引用。但是子控制器没有绑定到父控制器;它绑定到已解析的值。如果您查看 DOM,您将看到 &lt;town-detail town="::$resolve.town"&gt;&lt;/town-detail&gt;
  • (...继续) 我建议您更新 townId 状态参数,以便干净地重新获取城镇。如果 townId 没有改变,您可以使用{ reload: 'town' } 转换选项强制重新获取城镇解析。
  • 您好,感谢您的回答。我只是不明白,为什么我可以在父组件控制器中执行例如vm.town.x = 666 并且一切正常(更改在子状态组件中可见)。但仅通过调用服务BuildingUpgradeRest.update() 来更改 vm.town 是行不通的。如果我理解您的建议,这意味着我需要为城镇对象的每次更改调用我的休息服务 2 次(第一次调用更改,第二次调用状态解析)?
  • 这是因为vm.town.x 您正在更改对象的属性。因为两个控制器中都绑定了相同的对象,所以会反映更改。但是,更改vm.town 实际上会更改虚拟机对不同对象 的引用。在另一个控制器中,对原始对象的引用仍然是旧的。
  • 我不建议调用 REST 服务两次每次。我建议在保存后重新加载解析(从 REST 服务)。如果您确实需要改变子数据并将其反映在父数据中,则可以遵循此处概述的父/子通信模式:ui-router.github.io/guide/ng1/…

标签: javascript angularjs angular-ui-router angular-resource


【解决方案1】:
function TownCmpController(TownServices,Town,BuildingUpgradeRest) {
  var vm = this;
  this.upgradeBuilding = function(data) {
     BuildingUpgradeRest.update({townId:  vm.town.TownId,buildingId: data.building.BuildingId}).then(function (response) {
       vm.town = response;
     })
  }
}

您的服务返回承诺,因此您喜欢服务响应,然后设置 vm.towns

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多