angularjs 控制器中用Promise初始化数据时,model绑定不成功。

新手上路,请多包涵

在controller的初始化数据方法里用Promise绑定数据

controller init方法中,用storage返回的Promise初始化数据:

        storage.getCategoryList().then(function (res) {
            $scope.categoryList = res;
        });

storage组件中,先从sessionStorage中取数据,没取到再用APIService调接口从后台取数据,再将结果返回:

storage.getCategoryList = function () {
        return new Promise(function (resolve, reject) {
            let categoryList = sessionStorage.getItem('categoryList');
            if(categoryList == null || categoryList === undefined){
                APIService.getCategoryList().then(function (res) {
                    if(res.data.httpStatus === 200){
                        categoryList = res.data.categoryList;
                        sessionStorage.categorylist = categoryList;
                        resolve(categoryList);
                    }else{
                        reject();
                    }
                });
            }else{
                resolve(categoryList)
            }
        })
    }

前端html:

<div class="form_items_content_input form_items_content input-group">
                <input type="text" class="form-control" name="category" ng-model="category">
                <div class="input-group-btn">
                    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
                        选择分类
                        <span class="caret"></span>
                    </button>
                    <ul class="dropdown-menu">
                        <li ng-repeat="a in categoryList" ng-click="bindingCategory(a)"><a>{{a}}</a></li>
                    </ul>
                </div><!-- /btn-group -->
            </div>

这样子取数据后,categroyList绑定失败:

clipboard.png

将controller init方法改为直接从后台取数据却能成功:

APIService.getCategoryList().then(function (res) {
            if(res.data.httpStatus === 200){
                $scope.categoryList  = res.data.categoryList;
            }
        })

clipboard.png

在前面的方法中调用一次$apply更新数据也能成功:

storage.getCategoryList().then(function (res) {
            //此处直接赋值,数据无法绑定到view,需用$apply
            $scope.$apply(function () {
                $scope.categoryList = res;
            })
        });

于是我就想到可能是因为angularjs数据绑定已经完成了,第一种方法比较慢,还没将值赋给$scope.categoryList,才导致绑定失败,就将两种方法的执行时间比较了一下:

let start = new Date()
        storage.getCategoryList().then(function (res) {
            //此处直接赋值,数据无法绑定到view,需用$apply
            $scope.$apply(function () {
                $scope.categoryList = res;
                console.log(new Date().getTime() - start.getTime())
            })
        });
let start = new Date()
        APIService.getCategoryList().then(function (res) {
            if(res.data.httpStatus === 200){
                $scope.categoryList  = res.data.categoryList;
                console.log(new Date().getTime() - start.getTime())
            }
        })

结果发现前面的方法执行时间大概率优于后者,所以感到十分好奇,为什么前面的方法没法绑定数据,必须得用$apply才行??

有没有大神能帮忙解答一下这问题,感激不尽!

阅读 2.5k
2 个回答
✓ 已被采纳新手上路,请多包涵

脱离angular上下文,需要使用$apply强制数据同步??
在angular中调用非scope下的函数,如window下的方法,也是需要$apply才能够强制同步

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题