AngularJS-在POST

时间:2018-10-25 10:39:24

标签: javascript angularjs angular-promise angularjs-ng-include

我有一个向$ 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));

但是结果是我的模板没有更新,因此后端更改的零件的选项卡内容保持不变。

有什么想法如何触发受影响的标签页内容的更新?

0 个答案:

没有答案