AngularJS - Обновление шаблона, сгенерированного на лениво загруженной модели после POST - PullRequest
0 голосов
/ 25 октября 2018

У меня есть контроллер, зарегистрированный в $ 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));

Но результат в том, что мои шаблоны не обновляются, поэтому содержимое вкладки части, которая была изменена в бэкэнде, остается прежним.

Любойидеи, как вызвать обновление затрагиваемого содержимого вкладки?

...