Angularjs를 사용하여 ajax 요청이 완료 될 때까지 로딩 화면 (간단한 스피너)을 표시해야합니다. 코드 조각으로 아이디어를 제안하십시오.
답변
데이터로드 상태를 나타 내기 위해 범위 변수를 설정하는 대신 지시문이 모든 작업을 수행하도록하는 것이 좋습니다.
angular.module('directive.loading', [])
.directive('loading', ['$http' ,function ($http)
{
return {
restrict: 'A',
link: function (scope, elm, attrs)
{
scope.isLoading = function () {
return $http.pendingRequests.length > 0;
};
scope.$watch(scope.isLoading, function (v)
{
if(v){
elm.show();
}else{
elm.hide();
}
});
}
};
}]);
이 지시문을 사용하면 로딩 애니메이션 요소에 ‘loading’속성을 부여하기 만하면됩니다.
<div class="loading-spiner-holder" data-loading ><div class="loading-spiner"><img src="..." /></div></div>
페이지에로드 스피너가 여러 개있을 수 있습니다. 스피너를 배치하는 위치와 방법은 귀하에게 달려 있으며 지시문은 자동으로 켜고 끌 것입니다.
답변
여기에 예가 있습니다. bool과 함께 간단한 ng-show 방법을 사용합니다.
HTML
<div ng-show="loading" class="loading"><img src="...">LOADING...</div>
<div ng-repeat="car in cars">
<li>{{car.name}}</li>
</div>
<button ng-click="clickMe()" class="btn btn-primary">CLICK ME</button>
ANGULARJS
$scope.clickMe = function() {
$scope.loading = true;
$http.get('test.json')
.success(function(data) {
$scope.cars = data[0].cars;
$scope.loading = false;
});
}
물론 로딩 박스 html 코드를 지시어로 옮긴 다음 $ scope.loading에서 $ watch를 사용할 수 있습니다. 이 경우 :
HTML :
<loading></loading>
ANGULARJS 지시 :
.directive('loading', function () {
return {
restrict: 'E',
replace:true,
template: '<div class="loading"><img src="..."/>LOADING...</div>',
link: function (scope, element, attr) {
scope.$watch('loading', function (val) {
if (val)
$(element).show();
else
$(element).hide();
});
}
}
})
답변
이를 위해 ngProgress 를 사용 합니다.
HTML에 스크립트 / css 파일을 포함시킨 후 종속성에 ‘ngProgress’를 추가하십시오. 이렇게하면 경로 변경이 감지 될 때 트리거되는 이와 같은 것을 설정할 수 있습니다.
angular.module('app').run(function($rootScope, ngProgress) {
$rootScope.$on('$routeChangeStart', function(ev,data) {
ngProgress.start();
});
$rootScope.$on('$routeChangeSuccess', function(ev,data) {
ngProgress.complete();
});
});
AJAX 요청의 경우 다음과 같이 할 수 있습니다.
$scope.getLatest = function () {
ngProgress.start();
$http.get('/latest-goodies')
.success(function(data,status) {
$scope.latest = data;
ngProgress.complete();
})
.error(function(data,status) {
ngProgress.complete();
});
};
그렇게하기 전에 컨트롤러 종속성에 ‘ngProgress’를 추가하는 것을 잊지 마십시오. 여러 AJAX 요청을 수행하는 경우 기본 앱 범위에서 증분 변수를 사용하여 ‘ngProgress.complete ();’를 호출하기 전에 AJAX 요청이 언제 완료되었는지 추적합니다.
답변
Angular 문서에서 언급했듯이이 속성은 주로 디버깅 목적으로 사용되기 때문에 pendingRequests를 사용하는 것은 올바르지 않습니다.
내가 권장하는 것은 인터셉터를 사용하여 활성 비동기 호출이 있는지 확인하는 것입니다.
module.config(['$httpProvider', function ($httpProvider) {
$httpProvider.interceptors.push(function ($q, $rootScope) {
if ($rootScope.activeCalls == undefined) {
$rootScope.activeCalls = 0;
}
return {
request: function (config) {
$rootScope.activeCalls += 1;
return config;
},
requestError: function (rejection) {
$rootScope.activeCalls -= 1;
return rejection;
},
response: function (response) {
$rootScope.activeCalls -= 1;
return response;
},
responseError: function (rejection) {
$rootScope.activeCalls -= 1;
return rejection;
}
};
});
}]);
그런 다음 $ watch를 통해 지시문에서 activeCalls가 0인지 여부를 확인하십시오.
module.directive('loadingSpinner', function ($http) {
return {
restrict: 'A',
replace: true,
template: '<div class="loader unixloader" data-initialize="loader" data-delay="500"></div>',
link: function (scope, element, attrs) {
scope.$watch('activeCalls', function (newVal, oldVal) {
if (newVal == 0) {
$(element).hide();
}
else {
$(element).show();
}
});
}
};
});
답변
이를 수행하는 가장 좋은 방법은 사용자 지정 지시문 과 함께 응답 인터셉터 를 사용하는 것 입니다. 그리고 pub / sub 메커니즘을 사용 하여 프로세스를 더욱 향상시킬 수 있습니다. $ rootScope. $ broadcast & $ rootScope. $ on 메소드를 .
전체 프로세스가 잘 작성된 블로그 기사에 문서화되어 있으므로 여기서 다시 반복하지 않겠습니다. 필요한 구현에 대해서는 해당 기사를 참조하십시오.
답변
이 답변을 참조하여
https://stackoverflow.com/a/17144634/4146239
나에게는 최상의 솔루션이지만 jQuery 사용을 피하는 방법이 있습니다.
.directive('loading', function () {
return {
restrict: 'E',
replace:true,
template: '<div class="loading"><img src="http://www.nasa.gov/multimedia/videogallery/ajax-loader.gif" width="20" height="20" />LOADING...</div>',
link: function (scope, element, attr) {
scope.$watch('loading', function (val) {
if (val)
scope.loadingStatus = 'true';
else
scope.loadingStatus = 'false';
});
}
}
})
.controller('myController', function($scope, $http) {
$scope.cars = [];
$scope.clickMe = function() {
scope.loadingStatus = 'true'
$http.get('test.json')
.success(function(data) {
$scope.cars = data[0].cars;
$scope.loadingStatus = 'false';
});
}
});
<body ng-app="myApp" ng-controller="myController" ng-init="loadingStatus='true'">
<loading ng-show="loadingStatus" ></loading>
<div ng-repeat="car in cars">
<li>{{car.name}}</li>
</div>
<button ng-click="clickMe()" class="btn btn-primary">CLICK ME</button>
</body>
$ (element) .show (); 대체해야합니다. 및 (요소) .show (); $ scope.loadingStatus = ‘true’로; 그리고 $ scope.loadingStatus = ‘false’;
보다,이 변수를 사용하여 요소의 ng-show 속성을 설정해야합니다.
답변
Typescript 및 Angular 구현
지령
((): void=> {
"use strict";
angular.module("app").directive("busyindicator", busyIndicator);
function busyIndicator($http:ng.IHttpService): ng.IDirective {
var directive = <ng.IDirective>{
restrict: "A",
link(scope: Scope.IBusyIndicatorScope) {
scope.anyRequestInProgress = () => ($http.pendingRequests.length > 0);
scope.$watch(scope.anyRequestInProgress, x => {
if (x) {
scope.canShow = true;
} else {
scope.canShow = false;
}
});
}
};
return directive;
}
})();
범위
module App.Scope {
export interface IBusyIndicatorScope extends angular.IScope {
anyRequestInProgress: any;
canShow: boolean;
}
}
주형
<div id="activityspinner" ng-show="canShow" class="show" data-busyindicator>
</div>
CSS
#activityspinner
{
display : none;
}
#activityspinner.show {
display : block;
position : fixed;
z-index: 100;
background-image : url('data:image/gif;base64,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')
-ms-opacity : 0.4;
opacity : 0.4;
background-repeat : no-repeat;
background-position : center;
left : 0;
bottom : 0;
right : 0;
top : 0;
}
