我有一个向$ routeProvider注册的控制器,该控制器获得了注入的“服务”:
$routeProvider.when(..., { ..., controller: [ ..., 'Service', ]})
现在在控制器内部,我调用该服务以获取我的业务对象:
let initialPromises = {..., myObject: Service.getById(...) };
$q.all(initialPromises).then((resolvedPromises) => Object.assign($scope, resolvedPromises));
我的业务对象有点特殊,因为它的属性是延迟加载的。在后端中,仅获取对象本身的数据,而主对象组成的所有其他对象则被延迟加载。后端提供了使用HTTP标头 Link 获取成员对象的提示。
即。提取URL:https://path/to/my/object/(id)为每个需要导航为
的对象获取带有HTTP Link标头的平面JSON结构。Link: <https://path/to/my/object/(id)/children>; rel="children"
这指示“服务”为最初加载的名为“子级”的业务对象生成可延迟加载的属性,每当从其中读取一段javascript代码时都可以获取该属性。就我而言,这是在编译AngularJS模板时发生的。像这样:
<tr ng-repeat="child in myObject.children">
通过以下方法生成延迟加载的属性:
function defineProperty(target, link) {
let value = undefined,
isNotFetched = true;
Object.defineProperty(target, link.rel, {
get: function () {
if (isNotFetched) {
isNotFetched = false;
loadPropertyValue(link, target).then(
function (propValue) {
value = propValue;
},
(error => console.error('unable to load property ' + link.rel + ' for item ' + target.articleNumber, error))
);
}
return value;
},
set: function (newValue) {
value = newValue;
}
});
target[symbProp] = target[symbProp] || [];
target[symbProp].push(link.rel);
Object.defineProperty(target, '$' + link.rel, {
get: function () {
return loadPropertyValue(link, target);
}
});
target[symbProp].push('$' + link.rel);
}
,然后使用以下方法加载属性本身:
function loadPropertyValue(link, target) {
var resolvedUrl = resolveTagValues(link.url, target);
if (! angular.isDefined(ongoingRequests[resolvedUrl])) {
var promise = $q.resolve(
$window.fetch(
resolvedUrl,
{credentials: 'include', mode: 'cors'}
),
function (response) {
let jsonPromise = response.text().then(
function (data) {
if (data) {
return JSON.parse(data);
}
return undefined;
},
(error => console.error(error))
);
return $q.resolve(jsonPromise).then(
function (propertyValue) {
if (propertyValue !== undefined) {
return defineProperties(Restangular.stripRestangular(propertyValue), resolveLinks(response.headers.get('Link')));
}
return undefined;
}
);
},
(error => console.error(error))
);
ongoingRequests[resolvedUrl] = promise;
}
return ongoingRequests[resolvedUrl];
}
我的业务对象有点大,因此我添加了angular-bootstrap选项卡组件,将其分为几个逻辑部分。标签的内容使用 ng-include 加载,如下所示:
<uib-tab index="0" heading="Section X">
<div ng-include="'path/to/myobject/logical/part.template.html'"></div>
</uib-tab>
到目前为止,一切正常。让我再说一遍,以强调我的问题不是要让东西与延迟加载一起工作,或者到目前为止还没有说过的其他事情:“到目前为止,一切都很好。”
当我在一个
用户更改了对象的所需部分后,将其处理并发送到后端,然后更改受影响的部分,对象本身返回到前端,如下所示:
Service.save(processedObject).then(
function (savedObject) {
Object.assign($scope.myObject, savedObject);
$growl.info("Object " + $scope.myObject.name + ' was saved');
}, function (error) {
$growl.warning('Error when saving object - ' + error);
}
);
人们应该认为运行以下代码:
Object.assign($scope.myObject, savedObject);
将产生与运行相同的结果:
let initialPromises = {..., myObject: Service.getById(...) };
$q.all(initialPromises).then((resolvedPromises) => Object.assign($scope, resolvedPromises));
但是结果是我的模板没有更新,因此后端更改的零件的选项卡内容保持不变。
有什么想法如何触发受影响的标签页内容的更新?