在服务方法上使用 $interval 不起作用
Use $interval on a service method isn't working
我正在构建一个移动网络应用程序,用于检测用户浏览器是否可以访问互联网。
我正在使用 AngularJS 框架来实现这一点。我每 1000 毫秒从 AppData 调用一个服务方法来测试用户与 ajax 请求的连接。
PicController 将结果绑定到我的 html 视图。
我的想法是创建一个服务 AppData,它将存储我的应用程序的一般属性和方法。
这段代码根本行不通,我猜是方法不对,有高手能告诉我怎么做吗?
错误:
TypeError: Cannot read property 'online' of undefined
at isOnline (pictureViewer.js:24)
代码:
'use strict';
var picApp = angular.module('pictureViewerApp',[]);
picApp.run(['$interval','AppData', function($interval, AppData){
$interval(AppData.isOnline,1000);
}]);
picApp.controller("PicController",['$scope', 'AppData', function($scope, AppData){
$scope.online = AppData.online;
}]);
picApp.factory('AppData', ['$http', function($http) {
var AppData = {};
AppData.online = false;
AppData.isOnline = function() {
var appData = this;
$http.get('online.php').
success(function(data) {
appData.online = true;
}).
error(function() {
appData.online = false;
});
console.log("AppData.online = ", appData.online);
};
return AppData;
}]);
编辑:
错误恰好发生在这一行:
console.log("AppData.online = ", appData.online);
编辑 2:
如果我调用我的方法一次它工作正常,只有当我使用 $interval 调用它时才会出现问题。
谢谢
1) 您的视图不会更新,因为您的 $scope.online
绑定到 value
,而不是 reference
(object/array/function)。
2) 不使用 bind 就不能将 ´AppData.isOnline´ 作为参数传递(检查浏览器兼容性)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
检查这个工作示例:
var picApp = angular.module('pictureViewerApp',[]);
picApp.run(function(AppData, $interval) {
$interval(AppData.isOnline.bind(AppData), 1000);
/*
//Is same as
$interval(function(){
AppData.isOnline();
}, 1000);*/
});
picApp.controller("PicController",['$scope', 'AppData', function($scope, AppData){
$scope.AppData = AppData;
}]);
picApp.factory('AppData', function($q) {
var AppData = {
online: false
};
AppData.isOnline = function() {
var deferred = $q.defer();
// TODO: Use $http to load.
this.online = true;
deferred.resolve(true);
return deferred.promise;
};
return AppData;
});
<!DOCTYPE html>
<html ng-app="pictureViewerApp">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.0-rc.0/angular.js" data-semver="1.4.0-rc.0"></script>
</head>
<body ng-controller="PicController">
<p>User is online? {{AppData.online}}!</p>
</body>
</html>
我建议使用拦截器。只是检查它是否是正确的请求,如果它得到正确的 header,设置 ok,如果它不是 thur $injector
放置 rootScope,甚至广播这个事件。然后像请求者一样使用服务
picApp.service('AppData', function($http) {
this.getOnlineResponse = function(){
$http(someApiRequestPath);
}
return this;
});
我正在构建一个移动网络应用程序,用于检测用户浏览器是否可以访问互联网。
我正在使用 AngularJS 框架来实现这一点。我每 1000 毫秒从 AppData 调用一个服务方法来测试用户与 ajax 请求的连接。
PicController 将结果绑定到我的 html 视图。
我的想法是创建一个服务 AppData,它将存储我的应用程序的一般属性和方法。
这段代码根本行不通,我猜是方法不对,有高手能告诉我怎么做吗?
错误:
TypeError: Cannot read property 'online' of undefined
at isOnline (pictureViewer.js:24)
代码:
'use strict';
var picApp = angular.module('pictureViewerApp',[]);
picApp.run(['$interval','AppData', function($interval, AppData){
$interval(AppData.isOnline,1000);
}]);
picApp.controller("PicController",['$scope', 'AppData', function($scope, AppData){
$scope.online = AppData.online;
}]);
picApp.factory('AppData', ['$http', function($http) {
var AppData = {};
AppData.online = false;
AppData.isOnline = function() {
var appData = this;
$http.get('online.php').
success(function(data) {
appData.online = true;
}).
error(function() {
appData.online = false;
});
console.log("AppData.online = ", appData.online);
};
return AppData;
}]);
编辑: 错误恰好发生在这一行:
console.log("AppData.online = ", appData.online);
编辑 2: 如果我调用我的方法一次它工作正常,只有当我使用 $interval 调用它时才会出现问题。
谢谢
1) 您的视图不会更新,因为您的 $scope.online
绑定到 value
,而不是 reference
(object/array/function)。
2) 不使用 bind 就不能将 ´AppData.isOnline´ 作为参数传递(检查浏览器兼容性) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
检查这个工作示例:
var picApp = angular.module('pictureViewerApp',[]);
picApp.run(function(AppData, $interval) {
$interval(AppData.isOnline.bind(AppData), 1000);
/*
//Is same as
$interval(function(){
AppData.isOnline();
}, 1000);*/
});
picApp.controller("PicController",['$scope', 'AppData', function($scope, AppData){
$scope.AppData = AppData;
}]);
picApp.factory('AppData', function($q) {
var AppData = {
online: false
};
AppData.isOnline = function() {
var deferred = $q.defer();
// TODO: Use $http to load.
this.online = true;
deferred.resolve(true);
return deferred.promise;
};
return AppData;
});
<!DOCTYPE html>
<html ng-app="pictureViewerApp">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.0-rc.0/angular.js" data-semver="1.4.0-rc.0"></script>
</head>
<body ng-controller="PicController">
<p>User is online? {{AppData.online}}!</p>
</body>
</html>
我建议使用拦截器。只是检查它是否是正确的请求,如果它得到正确的 header,设置 ok,如果它不是 thur $injector
放置 rootScope,甚至广播这个事件。然后像请求者一样使用服务
picApp.service('AppData', function($http) {
this.getOnlineResponse = function(){
$http(someApiRequestPath);
}
return this;
});