我有用于检查与服务器的连接的代码.我的代码每60秒运行一次.代码运行后,它会创建一条消息,并显示在页面上.这是我到目前为止所拥有的:
检查的代码:
$interval(function () {
us.isConnected().then(closeConnect, openConnect);
}, 60 * 1000);
Run Code Online (Sandbox Code Playgroud)
执行检查的代码
isConnected = (): ng.IPromise<any> => {
var self = this;
var deferred = this.$q.defer();
this.$http({
method: 'GET',
url: self.ac.baseUrl + '/api/Connect/Verify'
})
.success(() => {
self.connects = 0;
self.connectMessage = null;
deferred.resolve();
})
.error(() => {
if (self.connects == 0) {
self.connectMessage = "Unable to establish a connection to the server. " + retryMessage();
} else if (self.connects == 1) {
self.connectMessage = "Unable to establish a connection to the server for " + self.connects + " minute" + retryMessage();
} else {
self.connectMessage = "Unable to establish a connection to the server for " + self.connects + " minutes." + retryMessage();
}
self.connects++;
deferred.reject();
});
return deferred.promise;
};
Run Code Online (Sandbox Code Playgroud)
我想做的是有一个名为retryMessage()的简单函数,它允许我给出这样的消息:
Unable to establish a connection to the server for 164 minutes.
Connection will be retried in 59 seconds.
Unable to establish a connection to the server for 164 minutes.
Connection will be retried in 58 seconds.
Unable to establish a connection to the server for 164 minutes.
Connection will be retried in 57 seconds.
...
Unable to establish a connection to the server for 164 minutes.
Connection will be retried in 1 seconds.
Unable to establish a connection to the server for 164 minutes.
Retrying connection now.
Unable to establish a connection to the server for 165 minutes.
Connection will be retried in 59 seconds.
Run Code Online (Sandbox Code Playgroud)
当重新检查时,向下计数秒数直到0.
任何人都可以在AngularJS中建议我可以实现这个倒计时吗?
做你正在尝试的一种可能的方法是与... $q.notify
一起使用$interval
.
其他消息可以通过解析和拒绝传递.当然,任何这样做的地方你都可以直接打印到日志服务,但我认为将这些消息与promise行为一起返回可能是合适的(如果你愿意的话,你甚至可以返回一个完整的对象)状态代码和其他数据以及消息).
在下面的示例中,我让控制器管理日志记录并将其输出限制为12行.我还指定了连接测试的参数,因此它尝试连接每60秒,20次(这些参数可以更改为尝试不同的间隔,不同的次数,或无限期).如果测试失败,它会每秒打印重试消息,直到重试尝试:
(function() {
"use strict";
var myApp = angular.module('myApp', []);
myApp.controller('MainController', ['$scope', 'us', '$log', MainController]);
myApp.service('us', ['$interval', '$q', '$http', '$log', usService]);
/* Controller */
function MainController($scope, us, $log) {
var _data = {
connectLog: null
},
_connectMessages = [],
_MAX_LOG_LINES = 12;
$scope.data = _data;
_log("Starting connection test...");
us.testConnection(60, 20) //60 seconds between tests, 20 tests (if no max specified, could run forever...)
.then(onTestsSuccessful, onTestsFailed, onNotifying);
function onTestsSuccessful(result) {
_log(result);
// do success stuff...
}
function onTestsFailed(result) {
_log(result);
// do failed stuff...
}
function onNotifying(result) {
_log(result);
//do retrying stuff...
}
function _log(message, deferOutput) {
//$log.debug(message);
_connectMessages.push(message);
if (_MAX_LOG_LINES && _connectMessages.length > _MAX_LOG_LINES) {
_connectMessages.splice(0, _connectMessages.length - _MAX_LOG_LINES);
}
if (!deferOutput) {
_data.connectLog = _connectMessages.join('\n');
}
}
}
/* Service */
function usService($interval, $q, $http, $log) {
var _testConnectionInterval,
_testsRun;
return {
testConnection: _startTestConnection
};
function _startTestConnection(secondsBetweenTests, maxTests) {
var deferred = $q.defer(),
connectAttempts = 0;
_cancelConnectionTest();
_connectionTest().then(onConnectionTestSuccess, onConnectionTestFail); //immediately do first test
_testsRun++;
if (secondsBetweenTests > 0) {
_testConnectionInterval = $interval(
function repeatConnectionTest() {
if (maxTests && _testsRun >= maxTests) {
return _cancelConnectionTest();
}
deferred.notify("Retrying connection now.");
_connectionTest().then(onConnectionTestSuccess, onConnectionTestFail);
_testsRun++;
},
secondsBetweenTests * 1000); //start the countdown to the next
}
function onConnectionTestSuccess(result) {
connectAttempts = 0;
if ((maxTests && _testsRun >= maxTests) || !secondsBetweenTests) {
deferred.resolve("Last connection test success, " + _testsRun + " tests complete.");
} else {
deferred.notify("Connection test success.");
}
}
function onConnectionTestFail(result) {
var minutesPassed = connectAttempts * secondsBetweenTests / 60,
minutesRoundedToTwoDec = +(Math.round(minutesPassed + "e+2") + "e-2");
var connectMessage = "Unable to establish a connection to the server" + (connectAttempts === 0 ? "." : " for " + minutesRoundedToTwoDec + " minute" + (minutesPassed > 1 ? "s." : "."));
connectAttempts++;
if ((maxTests && _testsRun >= maxTests) || !secondsBetweenTests) {
deferred.reject("Last connection test failed, " + _testsRun + " tests completed.");
} else {
deferred.notify(connectMessage);
deferred.notify("Connection will be retried in " + secondsBetweenTests + " seconds.");
var retryInterval = $interval(
function retryMessage(counter) {
deferred.notify(connectMessage);
var secondsLeft = (secondsBetweenTests - 1) - counter;
deferred.notify("Connection will be retried in " + secondsLeft + " second" + (secondsLeft > 1 ? "s." : "."));
if (!secondsLeft) {
$interval.cancel(retryInterval);
retryInterval = null;
}
},
1000, (secondsBetweenTests - 1));
}
}
return deferred.promise;
}
function _connectionTest() {
var deferred = $q.defer(),
getBroken = {
method: 'GET',
url: '/api/never/gonna/give/you/up'
};
$http(getBroken)
.success(function onSuccess() {
deferred.resolve('Success!');
})
.error(function onError() {
deferred.reject('Failure!');
});
return deferred.promise;
}
function _cancelConnectionTest() {
_testsRun = 0;
if (!_testConnectionInterval) {
$log.debug("No previously running connection test to cancel.");
return;
}
$log.debug("Cancelling connection test.");
$interval.cancel(_testConnectionInterval);
_testConnectionInterval = null;
}
}
})();
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.28/angular.min.js"></script>
<div ng-app="myApp">
<pre ng-controller="MainController">{{data.connectLog}}</pre>
</div>
Run Code Online (Sandbox Code Playgroud)
小智 6
您可以在60秒内完成倒计时,如下所示:
countdown(60);
function countdown(current_time){
if(current_time === 0){
//call function to connect to server
return;
}
else{
current_time--;
}
$scope.time = current_time;
$timeout(function(){countdown(current_time)}, 1000);
}
Run Code Online (Sandbox Code Playgroud)
我建议将错误消息放在html中并用一个ng-show
或隐藏它,ng-if
然后只需更改数字,这样就不需要反复追加所有文本了.
我认为没有必要使用指令,您可能可以在控制器内执行所有操作。但是您实现了closeConnection
,openConnection
您应该编辑这些方法添加 'start' 和 'stop' $interval
。
还要记住,$interval
需要最大递归次数,在这种情况下非常有用。
https://docs.angularjs.org/api/ng/service/ $interval
function controllerFunc($scope, $interval) {
var timer;
var lastConnection = 0;
$scope.message = '';
//this is what you already have
$interval(function () {
us.isConnected().then(closeConnect, openConnect);
}, 60 * 1000);
//...
function closeConnect() {
//...
$interval.cancel(timer);
lastConnection = 0;
}
function openConnect() {
//...
timer = $interval(timerCall, 1000, 60);
lastConnection++;
}
function timerCall(times) {
$scope.message += 'Unable to establish a connection to the server for ' + lastConnection + ' minutes. ';
var retry = 60 - times;
$scope.message += 'Connection will be retried in '+ retry +' seconds';
}
}
Run Code Online (Sandbox Code Playgroud)
格式化消息
$scope.message
在此示例中是一个纯字符串,因此您不会获得任何格式,但您可以将其放入ng-bind-html
指令中,然后将任何 html 标记添加到消息字符串中。
https://docs.angularjs.org/api/ng/directive/ngBindHtml
<div ng-bind-html="message"></div>
Run Code Online (Sandbox Code Playgroud)
所以改变js
$scope.message += '<p>Connection will be retried in '+ retry +' seconds</p>';
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2819 次 |
最近记录: |