[angularjs] AngularJS에서 모델 변경을 볼 때 초기로드를 어떻게 무시합니까?

단일 엔티티의 편집기 역할을하는 웹 페이지가 있는데 $ scope.fieldcontainer 속성에 깊은 그래프로 표시됩니다. $ resource를 통해 REST API에서 응답을 얻은 후 ‘fieldcontainer’에 시계를 추가합니다. 이 시계를 사용하여 페이지 / 엔티티가 “더러운”것인지 감지합니다. 지금은 저장 버튼을 바운스하지만 실제로 사용자가 모델을 더럽힐 때까지 저장 버튼을 보이지 않게하고 싶습니다.

내가 얻는 것은 시계의 단일 트리거입니다. 시계가 생성 된 직후 .fieldcontainer = … 할당이 발생하기 때문에 발생한다고 생각합니다. 나는 “dirtyCount”속성을 사용하여 초기 허위 경보를 흡수하려고 생각했지만 매우 해키 느낌이 들었습니다 … 그리고 이것을 처리하는 “각도 관용적”방법이 있어야한다고 생각했습니다-나는 유일한 사람이 아닙니다. 더러운 모델을 감지하기 위해 시계를 사용합니다.

시계를 설정 한 코드는 다음과 같습니다.

 $scope.fieldcontainer = Message.get({id: $scope.entityId },
            function(message,headers) {
                $scope.$watch('fieldcontainer',
                    function() {
                        console.log("model is dirty.");
                        if ($scope.visibility.saveButton) {
                            $('#saveMessageButtonRow').effect("bounce", { times:5, direction: 'right' }, 300);
                        }
                    }, true);
            });

“if (dirtyCount> 0)”으로 “UI dirtying”코드를 보호하는 것보다이 작업을 수행하는 더 확실한 방법이 있어야한다고 생각합니다.



답변

초기로드 직전에 플래그를 설정하고

var initializing = true

그런 다음 첫 $ watch가 실행되면

$scope.$watch('fieldcontainer', function() {
  if (initializing) {
    $timeout(function() { initializing = false; });
  } else {
    // do whatever you were going to do
  }
});

현재 다이제스트주기가 끝날 때 플래그가 해제되므로 다음 변경 사항이 차단되지 않습니다.


답변

리스너를 처음 호출하면 이전 값과 새 값이 동일합니다. 그래서 그냥 이렇게하십시오 :

$scope.$watch('fieldcontainer', function(newValue, oldValue) {
  if (newValue !== oldValue) {
    // do whatever you were going to do
  }
});

이것은 실제로 Angular 문서가 처리를 권장하는 방식입니다 .

감시자가 범위에 등록되면 리스너 fn이 비동기 적으로 ($ evalAsync를 통해) 호출되어 감시자를 초기화합니다. 드문 경우지만 watchExpression의 결과가 변경되지 않았을 때 리스너가 호출되므로 바람직하지 않습니다. 리스너 fn 내에서이 시나리오를 감지하기 위해 newVal과 oldVal을 비교할 수 있습니다. 이 두 값이 동일하면 (===) 초기화로 인해 리스너가 호출되었습니다.


답변

이 질문에 대한 답변을 받았지만 제안 사항이 있습니다.

$scope.$watch('fieldcontainer', function (new_fieldcontainer, old_fieldcontainer) {
    if (typeof old_fieldcontainer === 'undefined') return;

    // Other code for handling changed object here.
});

플래그를 사용하면 효과가 있지만 약간의 코드 냄새납니다 .


답변

현재 값을 처음로드하는 동안 이전 값 필드는 정의되지 않습니다. 따라서 아래 예제는 초기로드를 제외하는 데 도움이됩니다.

$scope.$watch('fieldcontainer',
  function(newValue, oldValue) {
    if (newValue && oldValue && newValue != oldValue) {
      // here what to do
    }
  }), true;


답변

새 val의 상태 만 유효합니다.

$scope.$watch('fieldcontainer',function(newVal) {
      if(angular.isDefined(newVal)){
          //Do something
      }
});


답변