Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/425.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在AngularJS中使用工厂和http_Javascript_Angularjs_Http_Factory - Fatal编程技术网

Javascript 在AngularJS中使用工厂和http

Javascript 在AngularJS中使用工厂和http,javascript,angularjs,http,factory,Javascript,Angularjs,Http,Factory,我刚刚开始学习angular,并且看到可以定义一个工厂用于多个控制器 我有下面的代码,它在“success”方法中返回我的结果。但不是在功能之外 我觉得这与异步有关,但如果是这样的话,我不太确定如何继续 如有任何帮助,我们将不胜感激,敬请提前感谢 var abyssApp = angular.module('abyssApp', []); abyssApp.factory('abyssData', function($http) { var result, produc

我刚刚开始学习angular,并且看到可以定义一个工厂用于多个控制器

我有下面的代码,它在“success”方法中返回我的结果。但不是在功能之外

我觉得这与异步有关,但如果是这样的话,我不太确定如何继续

如有任何帮助,我们将不胜感激,敬请提前感谢

var abyssApp = angular.module('abyssApp', []);

abyssApp.factory('abyssData', function($http) {
    var result,
        products = $http.get('http://abyss.local/products.php');

    products.success(function(data) {
        result = angular.fromJson(data);
        console.log('success: ', result);  // object with data in
    });

    console.log(result);  // undefined
});

abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
    $scope.items = abyssData;
    console.log('abyssData: ', abyssData);  // undefined
});

在“ItemListCtrl”中,应该注入从“AbysData”工厂创建的对象。然后,它应该返回$http PROMITE,并直接在控制器中,在成功回调中,您应该将返回的结果分配给$scope.items。这只是一种示例方法,有很多方法和模式可以帮助您解决这些问题

console.log(result);  // undefined

记录“未定义”,因为当您调用此行时,还没有响应。试着弄清楚什么是承诺以及AJAX调用是如何工作的,特别是应该定义什么“成功”和“错误”。

在“ItemListCtrl”中,您应该注入从“AbysData”工厂创建的对象。然后,它应该返回$http PROMITE,并直接在控制器中,在成功回调中,您应该将返回的结果分配给$scope.items。这只是一种示例方法,有很多方法和模式可以帮助您解决这些问题

console.log(result);  // undefined

记录“未定义”,因为当您调用此行时,还没有响应。试着弄清楚什么是承诺,AJAX调用到底是如何工作的,特别是应该定义什么“成功”和“错误”。

反过来说。首先,工厂应该返回一个值。该值是一个单例。这意味着在工厂被执行之后,它不会执行自己超过一次。您可以做的是返回一个引用您的结果的对象

abyssApp.factory('abyssData', function($http) {
    var ret = {},
        products = $http.get('http://abyss.local/products.php')

    products.success(function(data) {
        ret.result = angular.fromJson(data);
        console.log('success: ', result);  // object with data in
    });

    console.log(result);  // undefined

    return ret;
});

abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
    $scope.items = abyssData.result;
    console.log('abyssData: ', abyssData);  // undefined
});
但是这个解决方案闻起来不是很好。除非您的对象列表永远不会更新。返回在需要时可以查询的资源更有意义。不确定控制器何时加载,结果是否已经加载。这意味着访问AbysData.result可能首先返回未定义的
undefined
,然后返回其他内容

但老实说,你要做的应该是:

$resource

你可以有一个这样的工厂:

abyssApp.factory('AbyssData', ['$resource', function($resource) {
    return $resource('http://abyss.local/products.php')
}])

abyssApp.factory('abyssData', ['AbyssData', function(AbyssData) {
   return AbyssData.query();
}])
var abyssApp = angular.module('abyssApp', []);

abyssApp.factory('abyssData', function($http) {
    function abyssData() {
        var self = this;
        self.products = null;

        self.getProducts = function(){
            // return products if they are set already (cache)
            if (self.products) { return self.products; }
            $http.get('http://abyss.local/products.php').success(function(data){
                self.products = data;
                return self.products;
            });
        };
    }
    return new abyssData();
});

abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
    $scope.items = abyssData.getProducts();
});

看看这个:$resource

你有它的另一种方式。首先,工厂应该返回一个值。该值是一个单例。这意味着在工厂被执行之后,它不会执行自己超过一次。您可以做的是返回一个引用您的结果的对象

abyssApp.factory('abyssData', function($http) {
    var ret = {},
        products = $http.get('http://abyss.local/products.php')

    products.success(function(data) {
        ret.result = angular.fromJson(data);
        console.log('success: ', result);  // object with data in
    });

    console.log(result);  // undefined

    return ret;
});

abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
    $scope.items = abyssData.result;
    console.log('abyssData: ', abyssData);  // undefined
});
但是这个解决方案闻起来不是很好。除非您的对象列表永远不会更新。返回在需要时可以查询的资源更有意义。不确定控制器何时加载,结果是否已经加载。这意味着访问AbysData.result可能首先返回未定义的
undefined
,然后返回其他内容

但老实说,你要做的应该是:

$resource

你可以有一个这样的工厂:

abyssApp.factory('AbyssData', ['$resource', function($resource) {
    return $resource('http://abyss.local/products.php')
}])

abyssApp.factory('abyssData', ['AbyssData', function(AbyssData) {
   return AbyssData.query();
}])
var abyssApp = angular.module('abyssApp', []);

abyssApp.factory('abyssData', function($http) {
    function abyssData() {
        var self = this;
        self.products = null;

        self.getProducts = function(){
            // return products if they are set already (cache)
            if (self.products) { return self.products; }
            $http.get('http://abyss.local/products.php').success(function(data){
                self.products = data;
                return self.products;
            });
        };
    }
    return new abyssData();
});

abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
    $scope.items = abyssData.getProducts();
});
请查看:$resource

可能有三件事:

1) 显式声明依赖项:

abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
为了

2) 要使用所需的值,工厂必须返回该值,因此最终应返回“result”变量。 尝试更改xhr请求中常见的变量名“result”,以防止重写

3) 要防止在返回之前访问数据,请尝试给出方法而不是值:

abyssApp.factory('abyssData', function($http) {
    return {
        get: function(successCallback){ //your callback function
            $http.get('http://abyss.local/products.php')
                .success(function(){
                    if(successCallback){
                        successCallback.apply(arguments);
                    }
                });
        }
    }
}
要使用此更改,请执行以下操作:

$scope.items = abyssData;
为此

abyssData.get(function(data){
    $scope.items = data;
});
可能有三件事:

1) 显式声明依赖项:

abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
为了

2) 要使用所需的值,工厂必须返回该值,因此最终应返回“result”变量。 尝试更改xhr请求中常见的变量名“result”,以防止重写

3) 要防止在返回之前访问数据,请尝试给出方法而不是值:

abyssApp.factory('abyssData', function($http) {
    return {
        get: function(successCallback){ //your callback function
            $http.get('http://abyss.local/products.php')
                .success(function(){
                    if(successCallback){
                        successCallback.apply(arguments);
                    }
                });
        }
    }
}
要使用此更改,请执行以下操作:

$scope.items = abyssData;
为此

abyssData.get(function(data){
    $scope.items = data;
});

这里有一些编辑。请注意,我这样做没有真正检查,所以类型和错误是完全可能的,但它的要点应该是有意义的

var abyssApp = angular.module('abyssApp', []);

abyssApp.service('abyssData', function($http) {
    this.products = $http.get('http://abyss.local/products.php');
});

abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
    abyssData.products.then(function(data) {
        console.log(data);
        $scope.items = data;
    }).catch(function(err){console.log(err);});
});
我让它成为一个服务而不是一个工厂,因为你真的只需要一个服务(单件)。如果您要调用不同的URL,并且希望执行类似于
product=new abysdata('potates')
之类的操作,那么工厂是合适的

一般来说,$http返回一个promise对象,它本身不是您需要的数据,而是解析为您需要的数据。这种承诺模式在angular中重复了很多次(并且在其他javascript场合越来越流行,因为它非常棒(IMO))。这意味着,在promise对象上,调用.then()方法,并在解析promise时传入要调用的函数。$http解析为XHR的结果。其他的承诺可以解决其他问题


在Promission.then stack的末尾,最好使用.catch()调用,因为在Promission中抛出的异常通常会进入bitbucket,除非您显式查找它们。这是承诺工作方式的一个普遍缺陷,意味着你必须小心例外情况。对于较旧的JS引擎,您需要将其更改为.then()'catch',因为catch在某些地方是一个有趣的词。但我90%确信任何阻塞.catch的JS环境都不会以角度运行。

这里有一些编辑。请注意,我这样做没有真正检查,所以类型和错误是完全可能的,但它的要点应该是有意义的

var abyssApp = angular.module('abyssApp', []);

abyssApp.service('abyssData', function($http) {
    this.products = $http.get('http://abyss.local/products.php');
});

abyssApp.controller('ItemListCtrl', function($scope, abyssData) {
    abyssData.products.then(function(data) {
        console.log(data);
        $scope.items = data;
    }).catch(function(err){console.log(err);});
});
我让它成为一个服务而不是一个工厂,因为你真的只需要一个服务(单件)。如果您要调用不同的URL,并且希望执行以下操作,则工厂将是合适的