javascript - AngularJS 组件模式在 Promise 后不更新

标签 javascript angularjs angular-ui-router components angular-promise

我创建了一个带有组件的示例 Angular js 应用程序,并尝试从 Promise API 加载数据。

这里的问题是,当 promise 得到解决时,响应数据不会在 UI 中更新,如果我执行 $scope.$apply(),则 Modal 会更新。我尝试了 $onChanges 但这也没有帮助!

这不是正确的实现,对吧?请提供有关我的代码结构和此问题的注释。

我在这里缺少 Ant 的东西吗?

angular.module('detailapp', ['ui.router'])
    .component('app', {
        template: `
        <div class="container">
             <div ui-view></div>
        </div>
    `
    })
    .config(function ($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise('/');
        //Home or Default page
        $stateProvider.state('home', {
            url: '/',
            template: '<div>Home</div>'
        });
        //details, with id
        $stateProvider.state('detail', {
            url: '/:id',
            template: '<detail-component></detail-component>'
        });

    })
    .service('endPointService', ['$q', '$http', function ($q, $http) {
        return {
            getDetailUrl: function (id) {
                return 'https://api.github.com/users/' + id;
            },
            get: function (url, params) {
                return new Promise(function (resolve, reject) {
                    $http.get(
                        url, {
                            params: params
                        }
                    ).then(function (res) {
                        resolve(res);
                    }).catch(function (err) {
                        reject(err);
                    });
                });
            }
        }
    }])
    .factory('listService', ['endPointService', function listService(endPointService) {
        let serviceInstance = {};
        serviceInstance.getDetail = function (Id) {
            return endPointService.get(
                endPointService.getDetailUrl(Id)
            ).then((res) => {
                return res.data;
            });
        };
        return serviceInstance;
    }])
    .component('detailComponent', {
        template: `
    <div class="panel panel-default ">
      <div class="panel-heading">Detail Component: ID - {{vm.id}}</div>
        <div class="row">
                <div class="col-md-3 col-xs-3"><strong>Name</strong></div>
                <div class="col-md-9 col-xs-9"><span class="text-info pull-left">{{vm.obj.name}}</span>	       	       </div>
      </div>
      <div class="row">
                <div class="col-md-3 col-xs-3"><strong>Follow</strong></div>
                <div class="col-md-9 col-xs-9"><span class="text-info pull-left">{{vm.obj.followers_url}}</span>	       	       </div>
      </div>
    </div>`,
        controller: ['$scope', '$stateParams', 'listService', function detailController($scope, $stateParams, listService) {
            let vm = this;
            vm.id = $stateParams.id;
            vm.obj = {};
            vm.$onInit = function () {
                /*controller on init */
                vm.getDetails();
                console.log(`onInit ${JSON.stringify(vm.obj)}`);
            };
            // vm.$onChanges = function (changes) {
            //     console.log(`onChanges ${JSON.stringify(vm.obj)} ${JSON.stringify(vm.changes)}`);
            //     // if (changes && angular.isUndefined(changes.obj.previousValue) && angular.isDefined(changes.obj.currentValue)) {
            //     //     console.log('Changing the modal' + changes);
            //     //     vm.obj = changes.obj.currentValue;
            //     // }
            // };
            vm.getDetails = function () {
                listService.getDetail(vm.id).then(res => {
                    vm.obj = res;
                    $scope.$apply();
                    console.log(`api call ${JSON.stringify(vm.obj)}`);
                });

            };
        }],
        controllerAs: 'vm'
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.4.2/angular-ui-router.js"></script>

<body ng-app="detailapp">
    <div class="container-fluid">
        <app>app is loading here...!</app>
    </div>
</body>

最佳答案

在您的服务中,无需创建自定义 promise ,因为 $http 返回 promise 结果。只需返回请求

.service('endPointService', ['$q', '$http', function ($q, $http) {
        return {
            getDetailUrl: function (id) {
                return 'https://api.github.com/users/' + id;
            },
            get: function (url, params) {
                return $http.get(url)
            }
        }
    }])

再次在工厂中只需返回服务方法,而不是在其中解开 promise

.factory('listService', ['endPointService', function listService(endPointService) {
        let serviceInstance = {};
        serviceInstance.getDetail = function (Id) {
            return endPointService.get(endPointService.getDetailUrl(Id))
        };
        return serviceInstance;
    }])

关于javascript - AngularJS 组件模式在 Promise 后不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43720443/

相关文章:

angularjs - karma 报应/ Jasmine /PhantomJs : undefined is not a constructor

angularjs - Angular 的 e2e 测试中的页面对象设计模式

javascript - 以分钟为单位的日期时间差异

javascript - 回发期间的进度条 asp.net

javascript - AngularJS、UI Bootstrap 的选项卡和数据表

javascript - AngularJs 中带有嵌套 ui-view 的体面的 Url

javascript - 多个命名 View 未显示

javascript - Typescript 中的条件默认导出

Javascript从表单输入计算输入数字

angularjs - UI-Router 在页面刷新时给出无法获取错误