У меня есть контроллер, зарегистрированный в $ routeProvider, которому вводится «Сервис»:
$routeProvider.when(..., { ..., controller: [ ..., 'Service', ]})
Теперь внутри моего контроллера я вызываю сервис, чтобы получить мой бизнес-объект:
let initialPromises = {..., myObject: Service.getById(...) };
$q.all(initialPromises).then((resolvedPromises) => Object.assign($scope, resolvedPromises));
Мой бизнес-объект немного особенный в том, что его свойства загружаются с отложенной загрузкой.В бэкэнде выбираются только данные для самого объекта, а все остальные объекты, из которых состоит основной объект, загружаются с отложенной загрузкой.Бэкэнд предоставляет подсказки для извлечения объектов-членов с использованием HTTP-заголовка Link .
Ie.выборка URL: https://path/to/my/object/(id) выборка плоской структуры JSON с заголовками HTTP-ссылок для каждого объекта, к которому необходимо перейти, например,
Link: <https://path/to/my/object/(id)/children>; rel="children"
Это указывает «Сервису» на создание отложенной загрузкиСвойство изначально загруженного бизнес-объекта с именем «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));
Но результат в том, что мои шаблоны не обновляются, поэтому содержимое вкладки части, которая была изменена в бэкэнде, остается прежним.
Любойидеи, как вызвать обновление затрагиваемого содержимого вкладки?