2017-01-22 4 views
2

PouchDB와 데이터베이스의 조합으로 ionic app에서 Angular 2를 사용 중입니다. 성능상의 이유로 OnPush + Async 파이프를 모든 곳에서 사용하기로했습니다.각도 2 + OnPush : pouchdb 콜백에서 변경 감지가 작동하지 않음

@Injectable() 
export class Database { 
    foo$ = new BehaviorSubject(0); 

    (...) 

    sync(url, options) { 
    this.pouchdb.sync(url, options) 
     .on('change', this.changed.bind(this)); 
    this.foo$.subscribe(count => console.debug('the count is', count)); 
    } 

    changed() { 
    this.foo$.next(this.foo$.value + 1); 
    } 
} 

과 :

난 그냥 DB 변경의 수를 계산 데이터베이스 클래스가 : 지금은 pouchdb 이벤트가 변화의 원인의 경우는 템플릿에 반영되지 않는다는 사실을 우연히 발견 템플릿 안에 나는 숫자 표시 비동기 파이프를 사용

{{ db.foo$|async }} 

을하지만이 작동하지 않습니다 수는 데이터베이스 변경 (콘솔 출력은 데이터베이스 변경의 수를 표시)가있는 경우에도 붙어있다. 그러나 무언가를 클릭하면 숫자가 갑자기 올바른 값으로 이동합니다.

비동기 파이프가 관찰 가능에 가입함으로써 작동하고 일단이 관찰 가능 항목이 방출되면 템플리트 내의 값이 업데이트된다는 사실을 알고 놀랍습니다. 콘솔 출력에서 ​​볼 수 있듯이 관찰 가능한 출력물을 알고 있기 때문에 이것은 분명히 여기에서 작동하지 않지만 변경 사항은 템플릿에 반영되지 않습니다.

이 동작의 원인/변경 방법을 알고 있습니까?

추가 정보를 원하시면

는 문제가 발생 각도 pouchDB <의 조합이> 내가 템플릿 내부의 값을 원인이 기능을 대신

sync(url, options) { 
    window.setInterval(this.changed.bind(this), 1000); 
} 

을 사용입니다 있는지 확인하기 위해서 매초마다 올바르게 업데이트됩니다.

EDIT

I 밖으로 발견이 더미 코드

window.setInterval(() => {}, 1000); 

수정 문제, 아마 매초 변화 검출을 유발한다. 내가 이해하지 못하는 것은 왜 비동기 파이프가 파이프를 사용하지 않고 변경 사항을 감지하지 못하는 것입니까?

+0

저에게 더 많은 것이 있어야합니다. 이것이 실제로 문제의 일부인지 확인하기 위해 ChangeDetectionStrategy.OnPush를 제거합니다. 이걸 확인 했니? – corolla

+0

직감 : 데이터베이스의 두 인스턴스를보고 있습니다. 템플리트에 사용 된 것과 .sync가 호출 된 템플리트와 동일하지 않습니다. – corolla

+0

답변 해 주셔서 감사합니다. 당신이 옳았어요 책임있는 OnPush가 아니고 ChangeDetectionStrategy.Default에서도 마찬가지입니다. 그러나 나는 두 개의 서로 다른 데이터베이스 인스턴스가 없다는 것을 확신합니다. 다른 것을 발견했습니다.이 더미 코드를 실행하면 모든 것이 잘 작동합니다. window.setInterval (>) => {}, 1000); 내가 이해하는 한, 이것은 실제로 변경 감지의 문제인 것으로 보이며 setInterval은 매초마다 변경 감지를 트리거합니다. 하지만 비동기 파이프가 변경 사항을 감지하지 못하는 이유를 모르겠습니다 ... – highwaychile

답변

4

TL : 코드가 각도 영역 밖에서 실행되므로 변경 내용이 다음 변경 감지주기까지 각도로 처리되지 않습니다.

크롬 개발 도구를 사용하여 변경된 호출에 중단 점을 넣습니다. pouchdb 호출과 setInterval 사이의 호출 스택에 차이가 있는지 확인하십시오. 특히 setInterval에는 pouchdb 호출이 수행하지 않는 호출을 둘러싼 영역 조종이있을 수 있습니다. 그렇다면, 당신 수 : 초기화의 순서로

  • 봐 - see this SO - 또는 pouchdb 그렇지 않으면 원숭이 각 영역 내부의 약속을 호출하는 패치가 될 수 있다면.
  • 데이터베이스 생성자에 private zone: NgZone을 삽입하고 this.zone.run(() => this.foo$.next(this.foo$.value + 1));을 changed() 내부에 사용하여 각도 영역을 확보하십시오.

모두 실패한 경우 동굴에 들어가서 수동으로 변경 감지 (using ChangeDetectionRef) 플래그를 지정합니다.그러나 db를 사용하는 구성 요소에서이 작업을 수행해야하므로 절대적인 끔찍한 추상화 누출입니다.

즐기십시오. 당신이 찾은 것을 알려주십시오.

+0

고맙다. zone.run()은 임시 해결책으로 작동한다. 조금 더 시간이 지나면 문제를 자세히 살펴보고 내가 발견 한 것을 알려줍니다. – highwaychile

관련 문제