【问题标题】:Angular.js delaying controller initializationAngular.js 延迟控制器初始化
【发布时间】:2012-09-03 14:02:31
【问题描述】:

我想延迟控制器的初始化,直到必要的数据从服务器到达。

我找到了适用于 Angular 1.0.1 的解决方案:Delaying AngularJS route change until model loaded to prevent flicker,但无法让它与 Angular 1.1.0 一起使用

模板

<script type="text/ng-template" id="/editor-tpl.html">
Editor Template {{datasets}}
</script>
    <div ng-view>
</div>

​

JavaScript

function MyCtrl($scope) {    
    $scope.datasets = "initial value";
}

MyCtrl.resolve = {
    datasets : function($q, $http, $location) {
        var deferred = $q.defer();

        //use setTimeout instead of $http.get to simulate waiting for reply from server
        setTimeout(function(){
            console.log("whatever");
            deferred.resolve("updated value");
        }, 2000);

        return deferred.promise;
    }
};

var myApp = angular.module('myApp', [], function($routeProvider) {
    $routeProvider.when('/', {
        templateUrl: '/editor-tpl.html',
        controller: MyCtrl,
        resolve: MyCtrl.resolve
    });
});​

http://jsfiddle.net/dTJ9N/1/

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    您可以查看使用资源的几乎相同的问题here,但它与 $http 的工作方式相同。我认为这应该可行

    function MyCtrl($scope, datasets) {    
        $scope.datasets = datasets;
    }
    
    MyCtrl.resolve = {
        datasets: function($http, $q) {
            var deferred = $q.defer();
    
            $http({method: 'GET', url: '/someUrl'})
                .success(function(data) {
                    deferred.resolve(data)
            }
    
            return deferred.promise;
        }
    };
    
    var myApp = angular.module('myApp', [], function($routeProvider) {
        $routeProvider.when('/', {
            templateUrl: '/editor-tpl.html',
            controller: MyCtrl,
            resolve: MyCtrl.resolve
        });
    });​
    

    【讨论】:

    【解决方案2】:

    由于 $http 返回一个 Promise,创建自己的 deferred 只是为了在 http 数据到达时返回 Promise 会影响性能。你应该能够做到:

    MyCtrl.resolve = {
        datasets: function ($http) {
            return $http({method: 'GET', url: '/someUrl'});
        }
    };
    

    如果您需要对结果进行一些处理,请使用 .then,您的 Promise 将免费链接:

    MyCtrl.resolve = {
        datasets: function ($http) {
            return $http({method: 'GET', url: '/someUrl'})
                   .then (function (data) {
                       return frob (data);
                   });
        }
    };
    

    【讨论】:

    • 我想说,在这种情况下,用另一个 Promise 包装 $http 的 Promise 对性能的影响非常小,不值得担心。但是,排除额外的 Promise 所产生的更简洁的代码是值得追求的。
    • 代码很好很干净,但到今天为止,小提琴坏了,显示文档来源。对 Angular 来说太新了,除了注意到这一点之外没有太大帮助。
    • 小提琴没有坏,它显示了http请求的结果:)
    【解决方案3】:

    您总是可以将“ng-show”放在最外层的 DOM 元素上,并将其设置为您要等待的数据。

    对于 Angular JS 主页上列出的示例,您可以看到它是多么简单:http://plnkr.co/CQu8QB94Ra687IK6KgHn 所要做的就是 这样,在设置该值之前,表单不会显示。

    这种方式更直观,工作量更少。

    【讨论】:

    • 如果您有多个数据加载怎么办?你不知道哪一个会完成,因为它们都是异步运行的。例如...假设我需要在选择框中显示 5 个选项以及与第一个选项相关的所有数据,所以我可以预加载表单???
    • 如果你有五个,没问题,在每个加载后记下,一旦所有五个都完成了就开心。您只需要有一些带有数组的变量,并在每次加载数据后检查长度是否为 5,然后在 5 之后设置另一个 ng-show 所基于的变量并重置您的计数数组。
    猜你喜欢
    • 1970-01-01
    • 2020-05-10
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 2020-10-08
    • 2017-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多