zoukankan      html  css  js  c++  java
  • routeProvider

    In a previous post about testing I mentioned that route resolves can make authoring unit tests for a controller easier. Resolves can also help the user experience.

    A resolve is a property you can attach to a route in both ngRoute and the more robust UI router. A resolve contains one or more promises that must resolve successfully before the route will change. This means you can wait for data to become available before showing a view, and simplify the initialization of the model inside a controller because the initial data is given to the controller instead of the controller needing to go out and fetch the data.

    As an example, let’s use the following simple service which uses $q to simulate the async work required to fetch some data.

    app.factory("messageService", function($q){
        return {
            getMessage: function(){
                return $q.when("Hello World!");
            }
        };
    });

    And now the routing configuration that will use the service in a resolve.

    $routeProvider
        .when("/news", {
            templateUrl: "newsView.html",
            controller: "newsController",
            resolve: {
                message: function(messageService){
                    return messageService.getMessage();
            }
        }
    })

    Resolve is a property on the routing configuration, and each property on resolve can be an injectable function (meaning it can ask for service dependencies). The function should return a promise.

    When the promise completes successfully, the resolve property (message in this scenario) is available to inject into a controller function. In other words, all a controller needs to do to grab data gathered during resolve is to ask for the data using the same name as the resolve property (message).

    app.controller("newsController", function (message) {
        $scope.message = message;
    });

    You can work with multiple resolve properties. As an example, let’s introduce a 2nd service. Unlike the messageService, this service is a little bit slow.

    app.factory("greetingService", function($q, $timeout){
       return {
           getGreeting: function(){
               var deferred = $q.defer();
               $timeout(function(){
                   deferred.resolve("Allo!");
               },2000);
               return deferred.promise;
           }
       }
    });

    Now the resolve in the routing configuration has two promise producing functions.

    .when("/news", {
        templateUrl: "newsView.html",
        controller: "newsController",
        resolve: {
            message: function(messageService){
                return messageService.getMessage();
            },
            greeting: function(greetingService){
                return greetingService.getGreeting();
            }
        }
    })

    And the associated controller can ask for both message and greeting.

    app.controller("newsController", function ($scope, message, greeting) {
        $scope.message = message;
        $scope.greeting = greeting;
    });

    Composing Resolve

    Although there are benefits to moving code out of a controller, there are also drawbacks to having code inside the route definitions. For controllers that require a complicated setup I like to use a small service dedicated to providing resolve features for a controller. The service relies heavily on promise composition and might look like the following.

    app.factory("newsControllerInitialData", function(messageService, greetingService, $q) {
        return function() {
            var message = messageService.getMessage();
            var greeting = greetingService.getGreeting();
     
            return $q.all([message, greeting]).then(function(results){
                return {
                    message: results[0],
                    greeting: results[1]
                };
            });
        }
    });

    Not only is the code inside a service easier to test than the code inside a route definition, but the route definitions are also easier to read.

    .when("/news", {
        templateUrl: "newsView.html",
        controller: "newsController",
        resolve: {
            initialData: function(newsControllerInitialData){
                return newsControllerInitialData();
            }
        }
    })

    And the controller is also easy.

    app.controller("newsController", function ($scope, initialData) {
        $scope.message = initialData.message;
        $scope.greeting = initialData.greeting;
    });

    One of the keys to all of this working is $q.all, which is a beautiful way to compose promises and run requests in parallel.

  • 相关阅读:
    js 实现长按效果(类似安卓的)
    Java编程思想学习笔记(一)
    中文自然语言处理(NLP)(五)应用HanLP分词模块进行分词处理
    中文自然语言处理(NLP)(四)运用python二维字典和jieba实现词频的统计
    中文自然语言处理(NLP)(三)运用python jieba模块计算知识点当中关键词的词频
    中文自然语言处理(NLP)(二)python jieba模块的进一步学习和xlrd模块
    中文自然语言处理(NLP)(一)python jieba模块的初步使用
    正则表达式(几个例子)
    用户登陆界面(jquery)
    一个简单的注册页面,基于JS
  • 原文地址:https://www.cnblogs.com/jayruan/p/5496829.html
Copyright © 2011-2022 走看看