AnguarJS中鏈式的一種更合理寫法

Darren Ji發表於2016-01-27

 

假設有這樣的一個場景:

我們知道一個使用者某次航班,抽象成一個departure,大致是:

{userID : user.email,flightID : "UA_343223",date: "01/14/2014 8:00 AM"}

有關航班的,抽象成一個flight,大致是:

{id: flightID,pilot : "Captain Morgan", plane : {make  : "Boeing 747 RC",model : "TA-889"},status: "onTime"}


有關天氣情況的,抽象成forecast,大致是:

{date: date,forecast : "rain"}


我們的需求是:

● 顯示departure相關:departure.date
● 顯示flight相關:flight.plane.make, flight.plane.model
● 顯示foreacst相關:weather.forecast

實現邏輯大致是:

→ 根據departure中的flightID獲取flight
→ 根據departure中的date獲取forecast


首先模擬一些服務:

 

(function(angular){
    angular.module("FlightServices",[])
        .service("user", function(){
            return{
                email: 'exmaple@qq.com',
                repository:"https://github.com/ThomasBurleson/angularjs-FlightDashboard"
            };
        })
        .service("travelService", function(user, $q){
            return{
                //根據使用者獲取departure
                getDeparture: function(user){
                    var defer = $q.defer();

                    defer.resolve({
                        userID   : user.email,
                        flightID : "UA_343223",
                        date     : "01/14/2014 8:00 AM"
                    });
                    return defer.promise;
                },
                getFlight: function(flightID){
                    return $q.resolve({
                        id    : flightID,
                        pilot : "Captain Morgan",
                        plane : {
                            make  : "Boeing 747 RC",
                            model : "TA-889"
                        },
                        status: "onTime"
                    });
                }
            };
        })
        .service("weatherService", function($q){
           return {
             getForecast: function(date){
                 return $q.resolve({
                     date     : date,
                     forecast : "rain"
                 });
             }
           };
        });
}(window.angular));

 

以上,模擬了一些資料,讓我們最終能獲取到如下資料:

有關使用者的:

{
    email: 'exmaple@qq.com',
    repository:"https://github.com/ThomasBurleson/angularjs-FlightDashboard"
};

有關depature的,通過getDeparture(user)獲取到一個promise

{
    userID   : user.email,
    flightID : "UA_343223",
    date     : "01/14/2014 8:00 AM"
}

有關depatrue的,通過getFlight(flightID)獲取到一個promise

{
    id    : flightID,
    pilot : "Captain Morgan",
    plane : {
        make  : "Boeing 747 RC",
        model : "TA-889"
    },
    status: "onTime"
}

有關forecast的,通過getForecast(date)獲取到一個promise

{
     date     : date,
     forecast : "rain"
}

接下來就從以上服務所提供的promise資料中獲取,由於是promise,所有就可以then,可能會這樣寫:

 

var FlightDashboard = function($scope, user, travelService, weatherService){
    $scope.user = user;
    
    travelService
        .getDeparture(user.email) //第一個請求
        .then(function(depature){
            $scope.departure = depature;
            
            //第二個請求
            travelService
                .getFlight(departure.flightID)
                .then(function(flight){
                    $scope.flight = flight;
                    
                    //第三次請求
                    weatherService
                        .getForecast(departure.date)
                        .then(function(weather){
                            $scope.weather = weather;
                        })
                })
        })

};

 

但以上寫法的缺點是層級太多。一種更好的寫法是:

 

(function(){
    "use strict";

    var FlightDashboard = function($scope, user, travelService, weatherService){
            var loadDeparture = function (user) {
                return travelService
                    .getDeparture(user.email)
                    .then(function(departure){
                        $scope.departure = departure;
                        return departure.flighID;
                    });

            });
        },
        loadFlight = function(flightID){
            return travelService
                .getFlight(flightID)
                .then(function(flight){
                    $scope.flight = flight;
                    return flight;
                });
        },
        loadForecast = function(){
            return weatherService
                .getForecast($scope.departure.date)
                .then(function(weather){
                    $scope.weather = weather;
                    return weather;
                });
        };

    loadDeparture(user)
        .then(loadFlight)
        .then(loadForecast);

    $scope.user = user;
    $scope.departure = null;
    $scope.flight = null;
    $scope.weather = null;
    ;

    window.FlightDashboard = ["$scope","user","travelService", "weatherService", FlightDashboard];
}());

 

以上,loadDeparture返回的flightID作為loadFligth的引數。

 

相關文章