서비스 데이터 변경 시 범위 값 업데이트
내 앱에는 다음과 같은 서비스가 있습니다.
uaInProgressApp.factory('uaProgressService',
function(uaApiInterface, $timeout, $rootScope){
var factory = {};
factory.taskResource = uaApiInterface.taskResource()
factory.taskList = [];
factory.cron = undefined;
factory.updateTaskList = function() {
factory.taskResource.query(function(data){
factory.taskList = data;
$rootScope.$digest
console.log(factory.taskList);
});
factory.cron = $timeout(factory.updateTaskList, 5000);
}
factory.startCron = function () {
factory.cron = $timeout(factory.updateTaskList, 5000);
}
factory.stopCron = function (){
$timeout.cancel(factory.cron);
}
return factory;
});
그런 다음 다음과 같은 컨트롤러에서 사용합니다.
uaInProgressApp.controller('ua.InProgressController',
function ($scope, $rootScope, $routeParams, uaContext, uaProgressService) {
uaContext.getSession().then(function(){
uaContext.appName.set('Testing house');
uaContext.subAppName.set('In progress');
uaProgressService.startCron();
$scope.taskList = uaProgressService.taskList;
});
}
);
, 기본적으로는 업데이트입니다.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」factory.taskList
이 5개를 했습니다.factory.taskList
로로 합니다.$scope.taskList
여러 가지 $apply
,$digest
, 에 on on의 factory.taskList
되지 않고 뷰가 표시됩니다.$scope.taskList
.
템플릿에는 빈 상태로 남아 있습니다.이 변경 사항을 어떻게 전파할 수 있는지 알고 계십니까?
중$watch
문제를 해결할 수 있지만 가장 효율적인 해결책은 아닙니다.서비스에 데이터를 저장하는 방법을 변경할 수 있습니다.
수 입니다.taskList
는 스코프가 오래된 위치를 가리키고 있는 동안 새로운 값을 할당할 때마다 관련지어집니다.이 플랭크에서 이런 일이 일어나는 것을 볼 수 있습니다.
플렁크를 처음 로드할 때 Chrome을 사용하여 힙 스냅샷을 만듭니다.버튼을 클릭하면 리스트가 다른 메모리 위치를 가리키고 있는 동안 스코프가 가리키는 메모리 위치가 업데이트되지 않습니다.
를 포함하는 예: " " )를 서비스에 보류시키면 쉽게 할 수 .data:{task:[], x:[], z:[]}
이 경우 "data"는 절대 변경해서는 안 되지만 필요할 때마다 해당 구성원을 변경할 수 있습니다.그런 다음 이 데이터 변수를 범위로 전달하고 "데이터"를 다른 항목에 할당하여 재정의하지 않는 한 데이터 내부 필드가 변경될 때마다 범위가 해당 변수를 인식하고 올바르게 업데이트됩니다.
이 플랭크에서는 위에서 제시한 수정을 사용하여 동일한 예를 실행하고 있습니다.이 상황에서는 감시자를 사용할 필요가 없습니다.또한 뷰에서 뭔가 갱신되지 않은 경우 스코프만 실행하면 됩니다.$apply
뷰를 갱신합니다.
이렇게 하면 많은 변수를 감시해야 하는 경우 변경 및 추악한 설정을 위해 변수를 자주 비교하는 감시자가 필요하지 않습니다.이 접근법의 유일한 문제는 뷰(html)에 변수 이름만 있던 모든 것 앞에 "데이터"가 있다는 것입니다.
Angular(엠버 및 기타 프레임워크와 달리)는 반마법적으로 동기 상태를 유지하는 특별한 래핑된 객체를 제공하지 않습니다.조작하고 있는 오브젝트는 단순한 javascript 오브젝트로 다음과 같습니다.var a = b;
는 변수를 링크하지 않습니다.a
그리고.b
라고 말하면서$scope.taskList = uaProgressService.taskList
는 이들 2개의 값을 링크하지 않습니다.
이런 거를 위해서link
-ing,angular
의 값을 표시할 수 있습니다.uaProgressService.taskList
값을 갱신합니다.$scope
변경 시:
$scope.$watch(function () { return uaProgressService.taskList }, function (newVal, oldVal) {
if (typeof newVal !== 'undefined') {
$scope.taskList = uaProgressService.taskList;
}
});
첫 번째 표현은 에 전달되었습니다.$watch
함수는 모든 루프에서 실행됩니다.두 번째 인수는 새로운 값과 오래된 값으로 호출되는 함수입니다.
도움이 될지는 모르겠지만 제가 하고 있는 것은 함수를 $scope.value에 바인드하는 것입니다.예를들면
angular
.module("testApp", [])
.service("myDataService", function(){
this.dataContainer = {
valA : "car",
valB : "bike"
}
})
.controller("testCtrl", [
"$scope",
"myDataService",
function($scope, myDataService){
$scope.data = function(){
return myDataService.dataContainer;
};
}]);
그럼 DOM에 바인드하면 됩니다.
<li ng-repeat="(key,value) in data() "></li>
이렇게 하면 코드에 $watch를 사용하는 것을 피할 수 있습니다.
아니요.$watch
등이 필요합니다.다음을 간단히 정의할 수 있습니다.
uaInProgressApp.controller('ua.InProgressController',
function ($scope, $rootScope, $routeParams, uaContext, uaProgressService) {
uaContext.getSession().then(function(){
uaContext.appName.set('Testing house');
uaContext.subAppName.set('In progress');
uaProgressService.startCron();
});
$scope.getTaskList = function() {
return uaProgressService.taskList;
};
});
그 함수는getTaskList
소유하다$scope
수익률은 변경 시마다 평가(및 갱신)됩니다.uaProgressService.taskList
Lightweight 대안은 컨트롤러 초기화 중에 서비스에 설정된 알림 패턴에 가입하는 것입니다.
예를 들어 다음과 같습니다.
app.controller('YourCtrl'['yourSvc', function(yourSvc){
yourSvc.awaitUpdate('YourCtrl',function(){
$scope.someValue = yourSvc.someValue;
});
}]);
서비스에는 다음과 같은 것이 있습니다.
app.service('yourSvc', ['$http',function($http){
var self = this;
self.notificationSubscribers={};
self.awaitUpdate=function(key,callback){
self.notificationSubscribers[key]=callback;
};
self.notifySubscribers=function(){
angular.forEach(self.notificationSubscribers,
function(callback,key){
callback();
});
};
$http.get('someUrl').then(
function(response){
self.importantData=response.data;
self.notifySubscribers();
}
);
}]);
이것에 의해, 컨트롤러가 서비스로부터 갱신되었을 때에, 보다 세심하게 조정할 수 있습니다.
Gabriel Piacenti의 말처럼, 변화하는 데이터를 물체로 감싸면 시계가 필요하지 않다.
그러나 범위에서 변경된 서비스 데이터를 올바르게 업데이트하려면 서비스 데이터를 사용하는 컨트롤러의 범위 값이 변경 데이터(필드)를 직접 가리키지 않는 것이 중요합니다.대신 스코프 값은 변경 데이터를 줄바꿈하는 개체를 가리켜야 합니다.
다음 코드가 더 명확하게 설명할 것입니다.이 예에서는 번역에 NLS 서비스를 사용하고 있습니다.NLS 토큰이 http를 통해 업데이트되고 있습니다.
서비스:
app.factory('nlsService', ['$http', function($http) {
var data = {
get: {
ressources : "gdc.ressources",
maintenance : "gdc.mm.maintenance",
prewarning : "gdc.mobMaint.prewarning",
}
};
// ... asynchron change the data.get = ajaxResult.data...
return data;
}]);
컨트롤러 및 스코프 표현
app.controller('MenuCtrl', function($scope, nlsService)
{
$scope.NLS = nlsService;
}
);
<div ng-controller="MenuCtrl">
<span class="navPanelLiItemText">{{NLS.get.maintenance}}</span>
</div>
위의 코드는 동작합니다만, 우선 NLS 토큰에 직접 액세스 하고 싶다고 생각하고(다음 스니펫을 참조), 여기서 값이 갱신되지 않았습니다.
app.controller('MenuCtrl', function($scope, nlsService)
{
$scope.NLS = nlsService.get;
}
);
<div ng-controller="MenuCtrl">
<span class="navPanelLiItemText">{{NLS.maintenance}}</span>
</div>
언급URL : https://stackoverflow.com/questions/19744462/update-scope-value-when-service-data-is-changed
'programing' 카테고리의 다른 글
SQL에서 JSON으로 - SQL 2016에서 객체 배열에서 값 배열로 (0) | 2023.03.13 |
---|---|
JSON 구문은 오브젝트에 중복된 키를 허용합니까? (0) | 2023.03.13 |
Type Script:중복 식별자 'IteratorResult' (0) | 2023.03.13 |
JavaScript의 Json 데이터에서 백슬래시 제거 (0) | 2023.03.13 |
AngularJS $http, CORS 및 http 인증 (0) | 2023.03.08 |