提问人:rolinger 提问时间:8/16/2023 更新时间:8/16/2023 访问量:7
angularjs state cache false 阻止将 canvas 重新附加到 div
angularjs state cache false prevents re-attaching canvas to div
问:
我发现了一个问题,即用户转到 PageA,用户单击打开模态的按钮,模态启动 rest API 调用,并使用从调用返回的信息创建 qrCode 并将 qrCode 作为附加到 ng-repeat 中创建的 DIV。模式将每 5 分钟刷新一次 qrCodes(基于时间戳)。在 PageA 上,用户可以打开/关闭模态而不会出现问题。一切似乎都很好。<canvas>
但是,当用户关闭模态并离开 PageA,然后返回 PageA 并再次打开模态时,将创建 qrCodes,但无法再附加到 DIV。当模式打开时,我可以看到 API 调用再次发生,我可以看到 API 调用中填充特定字段的其他信息,并且我能尽我所能地告诉 qrCode 函数正在创建图像,但它无法再次附加 DIV。每隔 5 分钟,我就会看到 API 再次调用,但新的 qrCode 图像永远不会再次附加。在源代码中,我可以看到应该附加到的正确 DIV - 因此 DIV 元素确实存在。<canvas>
经过数小时的故障排除,我看到我的状态控制器用于此页面。出于各种原因,我需要将其设置为 false。但是一时兴起,我设置了此页面并再次测试......这一次问题没有发生。我可以离开 PageA 并再次返回,qrCode 图像现在正确附加到 DIV 并每 5 分钟正确刷新一次(并验证它们是新的 qrCode 图像)。cache: false
cache: true
这是怎么回事?由于其他原因,我需要该页面,但是我可以使此qrCode问题正常工作的唯一方法是设置。我该如何解决这个问题?cache: false
cache: true
州:
.state('tab.clubs', {
cache: true,
url: '/clubs',
params: tabParams,
views: {
'tab-clubs': {
templateUrl: 'templates/tab-clubs.html',
controller: 'ClubCtrl'
}
}
})
.state('tab.club-detail', {
cache: true, // true: everything works, false: fails after routing away/back to club-detail
url: '/clubs/:ceID',
params: tabParams,
views: {
'tab-clubs': {
templateUrl: 'templates/detail-clubs.html', //this is the page with the modal on it
controller: 'ClubDetailCtrl'
}
}
})
控制器:
$scope.ticketTimer ;
$scope.ticketCSS = {} ;
$scope.genQRCode = function() {
$scope.refreshTickets = 1 ;
clubService.getTickets($scope.club.cID,$scope.club.clID,$scope.club.ceID)
.then(function(response) {
$scope.refreshTickets = 0 ;
if (response.success == true) {
for (var x=0;x<response.tickets.length;x++) {
var ticket = response.tickets[x] ;
$scope.ticketCSS[ticket.ticketID] = {} ;
// clear existing <canvas> from ticketDIV otherwise
// the jQuery qrcode will just add more qrCodes to the DIV
angular.element('#ticketID_'+ticket.ticketID).empty() ;
if (ticket.scode == 0) {
var ts = new Date(new Date().getTime() + 5 * 60000).toISOString().slice(0,19).replace("T"," ") ;
$scope.ticketCSS[ticket.ticketID].status = "Open" ;
$scope.ticketCSS[ticket.ticketID].stampTitle = "Refresh" ;
$scope.ticketCSS[ticket.ticketID].stampText = ts ;
$scope.ticketCSS[ticket.ticketID].img = "img/LiveScanner.gif" ;
$scope.ticketCSS[ticket.ticketID].stampColor = "black" ;
} else if (ticket.scode == 1) {
var ts = new Date(ticket.sdate).toISOString().slice(0,19).replace("T"," ") ;
$scope.ticketCSS[ticket.ticketID].status = "Scanned" ;
$scope.ticketCSS[ticket.ticketID].stampTitle = "Scanned" ;
$scope.ticketCSS[ticket.ticketID].stampText = ts ;
$scope.ticketCSS[ticket.ticketID].stampColor = "green" ;
$scope.ticketCSS[ticket.ticketID].img = "img/scanned1.png" ;
} else if (ticket.scode == 2) {
var ts = new Date(ticket.sdate).toISOString().slice(0,19).replace("T"," ") ;
$scope.ticketCSS[ticket.ticketID].status = "Expired" ;
$scope.ticketCSS[ticket.ticketID].stampTitle = "Expired" ;
$scope.ticketCSS[ticket.ticketID].stampText = ts ;
$scope.ticketCSS[ticket.ticketID].img = "img/expired.png" ;
$scope.ticketCSS[ticket.ticketID].stampColor = "red" ;
}
if (ticket.ticketRefund == 0) {
var refund = "No" ;
} else {
var refund = "Yes" ;
}
$scope.ticketCSS[ticket.ticketID].refunds = refund ;
$scope.ticketCSS[ticket.ticketID].trans = "No" ;
$scope.ticketCSS[ticket.ticketID].desc = ticket.ticketDesc ;
// generate qrCode, this attaches a canvas to the specified element:
// http://jeromeetienne.github.com/jquery-qrcode
jQuery('#ticketID_'+ticket.ticketID).qrcode({width:150,height:150,text:ticket.liveCode}) ;
}
}
}) ;
// create timer to refresh tickets in 5 minutes
$scope.ticketTimer = $timeout(function(){
$scope.genQRCode() ;
},300000) ; // 5 minutes = 300000
} ;
$ionicModal.fromTemplateUrl('ticketModal.html', {
scope: $scope,
animation: 'slide-in-up',
backdrop: 'static',
backdropClickToClose:false,
focusFirstInput: false
}).then(function(modal) {
$scope.tixModal = modal;
});
$scope.openTicketModal = function(id) {
// this interval is need to let ng-repeat in modal populate
// before triggering the genQRCode() function - otherwise, the genQRCode()
// will create the code and try to attach the `canvas` to the DIV
// before the div is actually rendered - causing it to fail.
//
// this is needed because modal template/scripts are loaded into memory
// when page/controller is loaded (even before modal is opened) causing genQRCode()
// to initialize cause the same DIV not yet created issue above. Not certain how to get
// ng-repeat to call function on $last element AFTER the modal is opened. bizarre behavior.
$scope.ticketInit = $interval(function() {
var tid = $scope.club.tickets.length-1 ;
var tik = $scope.club.tickets[tid] ;
//if (angular.element(document.querySelector('#ticketID_'+tid))) {
if (angular.element('#ticketID_'+tik.ticketID).length > 0) {
$interval.cancel($scope.ticketInit) ;
$scope.genQRCode() ;
}
},100) ;
//$scope.tixModal.show() ;
$rootScope.globalModalShow($scope.tixModal) ;
} ;
$scope.closeTicketModal = function(id) {
if ($scope.ticketTimer !== null) {
$timeout.cancel($scope.ticketTimer) ;
}
//$scope.tixModal.hide() ;
$rootScope.globalModalClose($scope.tixModal) ;
} ;
HTML格式:
<div id="ticketContainer" ng-show="!refreshTickets" style="width:90%;margin-left:5%;margin-top:10px;overflow-y:hidden;">
<div ng-repeat="ticket in club.tickets" id="ticketDiv_{{ticket.ticketID}}" style="position:relative;font-weight:bolder;min-width:100%;border:1px solid black;margin-bottom:20px;;" class="">
<div id="ticketCount_{{ticket.ticketID}}" style="text-align:center;">{{$index+1}} of {{club.tickets.length}}</div>
<div id="ticketScanner_{{ticket.ticketID}}" class="centerDivContents" style="position:absolute;margin-top:10px;">
<img id="ticketImg_{{ticket.ticketID}}" ng-src="{{ticketCSS[ticket.ticketID].img}}">
</div>
<div id="ticketID_{{ticket.ticketID}}"class="centerDivContents" style="margin-top:20px;" ></div>
<div style="margin:15px;">
<div id="ticketName_{{ticket.ticketID}}" style="">Type: {{ticket.ticketName}}</div>
<div id="ticketStatus_{{ticket.ticketID}}" style="">Status: <span style="color:{{ticketCSS[ticket.ticketID].stampColor}}">{{ticketCSS[ticket.ticketID].status}}</span></div>
<div id="ticketStamp_{{ticket.ticketID}}" style="">{{ticketCSS[ticket.ticketID].stampTitle}}: <span style="color:{{ticketCSS[ticket.ticketID].stampColor}}">{{ticketCSS[ticket.ticketID].stampText}}</span></div>
<div id="ticketRefund_{{ticket.ticketID}}" style="">Refunds: <span style="">{{ticketCSS[ticket.ticketID].refunds}}</span></div>
<div id="ticketTrans_{{ticket.ticketID}}" style="">Transfers: <span style="">{{ticketCSS[ticket.ticketID].trans}}</span></div>
<div id="ticketDesc_{{ticket.ticketID}}" style="white-space:break-spaces;">Desc: {{ticket.ticketDesc}}</div>
</div>
</div>
</div>
答: 暂无答案
评论