AngularJS如何从外部函数访问本地范围?

时间:2016-11-24 02:06:06

标签: angularjs

我的服务中有此代码

orderSewaService.vehicleDetail = function (license_plate) {

        //var defer = $q.defer();

        var config = {
            headers: {
                'X-Parse-Application-Id': parseAppId
            },
            params: {
                where: {
                    vehicle_license_plate: license_plate,
                    vehicle_status: 'available'
                },
                limit: 1,
                include: 'car_id.car_class_id,pool_id.city_id,partner_id.user_id'   
            }

        }

        return $http.get('http://128.199.249.233:1337/parse/classes/vehicle', config).then(function (response) {
            var detail = {
                license_plate: response.data.results[0].vehicle_license_plate,
                photo: response.data.results[0].vehicle_photo,
                partner_name: response.data.results[0].partner_id.user_id.full_name,
                year: response.data.results[0].vehicle_year,
                class: response.data.results[0].car_id.car_class_id.name,
                pool_address: response.data.results[0].pool_id.pool_address,
                city: response.data.results[0].pool_id.city_id.city_name,
                zone_id: response.data.results[0].zone_id.objectId,
                car_class_id: response.data.results[0].car_id.car_class_id.objectId         
            };

            return detail;

            //defer.resolve(detail);
        }, function (error) {
            //defer.reject(error);
            return error;
        });             

        //return defer.promise;     

    };

在我的控制器中

$scope.vehicle = {};
 orderSewaService.vehicleDetail($routeParams.license_plate).then(function(response){
                $scope.vehicle = response;//rendered in view
                console.log($scope.vehicle); //log object success
            }, function (error) {
                console.log(error);
            });

            console.log($scope.vehicle); //doesn't work //empty object
            //My goal is I will call other service function like this
            orderSewaService.infoTarif($scope.vehicle.zone_id, $scope.vehicle.car_class_id).then(...);

已经阅读了这个access scope data from outside function,但看起来很复杂或不适合我的简单目标。

我如何访问$scope.vehicle外部功能或如何实现目标?

在这种情况下,我不认为$rootScope是一个很好的解决方案。

3 个答案:

答案 0 :(得分:2)

你需要在函数调用之外声明$ scope.vehicle,

在开始的控制器的某个地方,

如果它是一个数组

$scope.vehicle =[];

答案 1 :(得分:0)

问题在于此控制器代码流的工作方式。

$scope.vehicle = {}; //vehicle property is declared and defined as empty obj in the $scope

orderSewaService.vehicleDetail($routeParams.license_plate) 这是一个ajax调用,js调用这个方法,然后在这个方法结束后进入下一行,即             console.log($scope.vehicle);无需等待调用返回并使用您的回复填充$ scope.vehicle。

所以,试试这个:

在控制器中:

`

$scope.vehicle = {};
orderSewaService.vehicleDetail($routeParams.license_plate).then(function(response){
                $scope.vehicle = response;//rendered in view
                getInfoTarif();
            }, function (error) {
                console.log(error);
            });
function getInfoTarif(){
console.log($scope.vehicle);
orderSewaService.infoTarif($scope.vehicle.zone_id,$scope.vehicle.car_class_id).then(...);
}

`

答案 2 :(得分:0)

我认为这个问题有两个问题。

首先 - 同步&异步方法

由于orderSewaService.vehicleDetail是异步的,$scope.vehicle将为空。

如果您不确定这意味着什么,请比较两者:

var foo = null;

foo = ['a','b'];

console.log(foo); // ['a','b']

var foo = null;

setTimeout(function(){
    foo = ['a','b'];
    console.log(foo); // array
}, 500); // or any value including zero

console.log(foo); // null

最后,您的代码应如下所示:

$scope.vehicle = {};
orderSewaService
    .vehicleDetail($routeParams.license_plate)
    .then(function(response){
        $scope.vehicle = response;//rendered in view
        console.log($scope.vehicle); //log object success

        //My goal is I will call other service function like this
        orderSewaService.infoTarif($scope.vehicle.zone_id, $scope.vehicle.car_class_id).then(...);

    }, function (error) {
        console.log(error);
    });

如果您对此感兴趣,有大量文章和文档可以描述这一点。

其次 - 在到达控制器之前加载内容

现在,根据您描述问题的方式,您似乎还希望在到达控制器之前基于URL参数加载orderSewaService.vehicleDetail的内容。否则,您必须在每个控制器中调用orderSewaService.vehicleDetailorderSewaService.infoTarif

更简洁,更常见的方法是使用ui-router' $stateProviderTutorials here

如果您从他们的文档中运行一些示例,您可以将依赖项注入控制器,如下所示:

<强> app.route.js

$stateProvider
.state('vehicles', {
    url: '/vehicles',
    resolve: { 
        vehicles: ['VehiclesService', function(VehiclesService){
            return VehiclesService.getAll();
        }]
    },
    controller: 'VehiclesListCtrl',
    templateUrl: 'vehicles.html'
})
.state('vehicles.detail', {
    url: '/vehicles/:vehicleId',
    resolve: { 
        info: ['VehiclesService', '$stateParams', function(VehiclesService, $stateParams){
            return VehiclesService.get($stateParams.vehicleId)
                 .then(function(vehicle){
                     return orderSewaService.infoTarif(vehicle.zone_id, vehicle.car_class_id)
                     .then(function(tarif){
                         return {
                             vehicle: vehicle,
                             tarif: tarif
                         };
                     });
                 });
        }]
    },
    controller: 'VehicleDetailCtrl',
    templateUrl: 'vehicle.detail.html'
});

<强> vehicle.detail.controller.js

.controller('VehicleDetailCtrl', VehicleDetailCtrl);

    VehicleDetailCtrl.$inject = [
        '$scope',
        'info'
    ];

    function VehicleDetailCtrl(
        $scope,
        info
    ) {
        console.log('vehicle %o tarif %o', info.vehicle, info.tarif);
    }

<强> vehicles.controller.js

.controller('VehiclesCtrl', VehiclesCtrl);

    VehiclesCtrl.$inject = [
        '$scope',
        'vehicles'
    ];

    function VehiclesCtrl(
        $scope,
        vehicles
    ) {
        console.log('vehicles list %o', vehicles);
    }

要访问此状态,您需要执行类似

的操作

<强> menu.html

<a ui-sref="vehicles.detail({vehicleId: 1234})">

为了便于说明,我故意没有将vehicles路线摘要。如果要创建嵌套状态/视图,可能需要look into that。 我希望这会有所帮助。