【发布时间】: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,您将看到<town-detail town="::$resolve.town"></town-detail> -
(...继续) 我建议您更新
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