programing

AngularJS : $scope.$watch가 사용자 지정 지시에 따라 $resource에서 가져온 값을 업데이트하지 않습니다.

itmemos 2023. 10. 19. 22:01
반응형

AngularJS : $scope.$watch가 사용자 지정 지시에 따라 $resource에서 가져온 값을 업데이트하지 않습니다.

사용자 지정 지침에 문제가 있어서 미칠 지경입니다.다음 사용자 지정(속성) 지시문을 작성하려고 합니다.

angular.module('componentes', [])
    .directive("seatMap", function (){
        return {
            restrict: 'A',
            link: function(scope, element, attrs, controller){

                function updateSeatInfo(scope, element){
                    var txt = "";
                    for (var i in scope.seats)
                        txt = txt + scope.seats[i].id + " ";
                    $(element).text("seat ids: "+txt);
                }

                /* 
                    // This is working, but it's kind of dirty...
                    $timeout(function(){updateSeatInfo(scope,element);}, 1000);
                */

                scope.$watch('seats', function(newval, oldval){
                    console.log(newval, oldval);
                    updateSeatInfo(scope,element);
                });
            }
        }
    });

이 "속성 유형" 지침(seatMap이라고 함)은 $resource service(아래 코드 참조)를 통해 서버에서 가져올 좌석 ID(예: 극장의 경우) 목록을 분할(요소)에 표시하려고 합니다.

저는 이 간단한 부분 html을 사용하고 있습니다.

<div>
    <!-- This is actually working -->
    <ul>
        <li ng-repeat="seat in seats">{{seat.id}}</li>
    </ul>

    <!-- This is not... -->
    <div style="border: 1px dotted black" seat-map></div>
</div>

그리고 이것이 스코프를 로드하는 컨트롤러입니다.

function SeatsCtrl($scope, Seats) {
    $scope.sessionId = "12345";
    $scope.zoneId = "A";
    $scope.seats = Seats.query({sessionId: $scope.sessionId, zoneId: $scope.zoneId});
    $scope.max_seats = 4;
}

여기서 "좌석"이란 $리소스를 사용하여 서버에서 JSON을 가져오는 간단한 서비스입니다.

angular.module('myApp.services', ['ngResource'])
    .factory('Seats', function($resource){
        return $resource('json/seats-:sessionId-:zoneId.json', {}, {});
    })
;

app.js (asientos_libres.html은 제가 사용하던 부분입니다):

angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'componentes']).
  config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/view1', {templateUrl: 'partials/asientos_libres.html', controller: SeatsCtrl});
    $routeProvider.otherwise({redirectTo: '/view1'});
  }]);

문제는, 제가 '범위'를 설정했음에도 불구하고 말입니다."seats" 속성이 ID 목록을 업데이트하기 위해 변경되었는지 확인할 수 있도록 명령어의 링크 기능에 $watch"가 있습니다. 현재 $scope이 작동하지 않습니다.("query"라고 할 때) 컨트롤러에서 좌석이 변경되고 있습니다.

코드에서 볼 수 있듯이, $timeout을 사용하여 "updateSeatInfo"의 출시를 지연시키려 했지만, 유감스럽게도 그것이 가장 현명한 해결책은 아닌 것 같습니다.

저는 또한 JSON 요청을 하지 않고 $scope로 된 하드 코딩된 사전을 사용하려고 했습니다.좌석과 작동을 해서 동기화의 문제인 것 같습니다.

참고: updateSeatInfo는 테스트 기능일 뿐이며 실제 사용할 기능은 좀 더 복잡합니다.

어떻게 대처해야 할지 조언해 주시겠어요?

미리 감사드립니다!

편집 1: 조언에 대한 Supr 덕분에 라우터를 사용하여 SeatsCtrl을 호출하는 app.js를 추가했습니다.하지만 저는 여전히 같은 문제를 안고 있습니다.

편집 2: 해결!(?)좋아요! 최선이 아닐 수도 있지만 제대로 작동하는 해결책을 찾은 것 같아요! :) 여기 http://docs.angularjs.org/api/ng.$timeout, 에서 볼 수 있는 한 우리는 지체 없이 $ timeout(setTimeout 위에 포장지)을 사용할 수 있습니다!$timeout 내에서 코드 실행을 인위적으로 지연하는 것이 아니라 비동기 요청이 완료될 때까지 실행하지 말라는 지시를 내린 것이기 때문에 매우 좋습니다.

오랜 기다림의 요청에도 효과가 있기를...

만약 누군가 그것을 고치는 더 좋은 방법을 안다면, 제발 말해주세요!

문제는 시계가 기본적으로 객체 대신 참조를 비교한다는 것입니다.값을 대신 비교하려면 끝까지 참입니다.

scope.$watch('seats', function(newval, oldval){
                console.log(newval, oldval);
                updateSeatInfo(scope,element);
            }, true);

저도 이런 문제가 있었습니다.그것은 내 변수가 처음에 범위에 '정의되지 않은' 것으로 정의되지 않았기 때문입니다.Watch는 정의되지 않은 변수에서는 작동하지 않는 것 같습니다.결국 명백해 보입니다.

저는 처음에 시계를 사용하여 컨트롤러에 의해 변수가 효과적으로 설정될 때 트리거하려고 했습니다.예:

myApp.controller('Tree', function($scope, Tree) {

Tree.get({},
function(data) { // SUCCESS
    console.log("call api Tree.get succeed");
    $scope.treeData = data;
},

function(data) { // FAILURE
    console.log("call api Tree.get failed");
    $scope.treeData = {};
});
});

서비스를 호출하기 전에 변수를 빈 개체로 초기화하여 해결했습니다.

myApp.controller('Tree', function($scope, Tree) {

$scope.treeData = {};      // HERE

Tree.get({},
function(data) { // SUCCESS
    console.log("call api Tree.get succeed");
    $scope.treeData = data;
},

function(data) { // FAILURE
    console.log("call api Tree.get failed");
    $scope.treeData = {};
});
});

그 경우 watch는 변수의 변화를 감지할 수 있었습니다.

당신이 사용하는 것이 보이지 않습니다.SeatsCtrl-컨트롤러는 아무데나?어떻게 사용되고 있습니까?활성화되어 있고 쿼리가 실제로 수행되는지 확인했습니까?

SeatsCtrl이 사용 중인지 확인하는 가장 빠른 방법은 간단히 다음을 추가하는 것입니다.console.log('SeatsCtrl actived!');그 안에그렇지 않은 경우 추가합니다.ng-controller="SeatsCtrl"div.

컨트롤러 내부의 좌석에 직접 시계와 로그를 설치하여 스코프 문제가 없는지 확인할 수도 있습니다.

저도 이런 문제가 있습니다.Angular에서 문제가 생긴 것 같습니다.GitHub에는 이 문제를 해결할 수 있는 "$자원 선물을 제공"할 수 있는 티켓이 있습니다. 실제로 필요한 것은 보유한 자원에 대한 약속 객체에 대한 액세스이기 때문입니다.

아니면, 그 약속이 해결될 때까지 감시자들은 발포를 기다릴 수도 있습니다.

한편, 시간 초과를 필요로 하지 않는 이 문제를 해결하는 조금 더 훌륭한 방법은 $리소스의 성공 콜백에서 관찰 중인 스코프 속성을 재할당하는 것입니다.이로 인해 적절한 시간에 감시자가 다시 발사됩니다.

지연되지 않는 시간 초과는 지연된 함수를 현재 스택의 끝에 평가하는 것입니다. - 당신의 경우, 당신의 자원은 그때까지 해결되었지만, 서버가 월요일의 경우라면 이 문제가 발생할 수 있습니다.

예:

$scope.myAttr = MyResource.fetch(
  function (resource) { $scope.myAttr = new MyResource(angular.copy(resource)); }
);

언급URL : https://stackoverflow.com/questions/11135864/angularjs-scope-watch-is-not-updating-value-fetched-from-resource-on-custom

반응형