2017-10-09 3 views
5

이전에 대규모 2 각도 앱을 사용한 경험이 있습니다. 나는 렌더링 사이클을 통제하에 두는 것에 정말로주의를 기울였다. 로그를 유지하는 것은 어떻게되는지 조사하는 것입니다.각도 2에서 렌더링주기를 저장하기 위해 리졸버 대신 가드를 사용해야합니까?

컨트롤러

public debugTemplate() { 
    DEBUG.render && debug('Render FooCmp'); 
} 

템플릿

{{ debugTemplate() }} 

I 스마트 구성 요소 만 ngrx 상태를 저장 구독을 사용했습니다. 내가 ChangeDetectionStrategy.OnPush

// Ngrx state store subscription 
this._fooService.foo$().subscribe(exp => this.foo = exp); 

ng serve --prod --aot를 사용하여 가드

import { Injectable } from '@angular/core'; 
import { CanActivate, ActivatedRouteSnapshot, 
    RouterStateSnapshot } from '@angular/router'; 
import { Observable } from 'rxjs/Observable'; 
import { environment } from '../../../environments/environment'; 
import { DEBUG } from '../../../config/config'; 
import * as Debug from 'debug'; 

// Interfaces 
import { Foo } from '../interfaces/foo'; 

// Services 
import { BarService } from '../services/bar.service'; 
import { FooService } from '../services/foo.service'; 

// Debug 
const debugOff = (...any) => { }, debug = Debug('app:FooPageGuard'); 

@Injectable() 
export class FooPageGuard implements CanActivate { 

    constructor(
     private _barService: BarService, 
     private _fooService: FooService 
    ) { 
     DEBUG.constr && debug('Construct FooPageGuard'); 
    } 

    canActivate(
     route: ActivatedRouteSnapshot, 
     state: RouterStateSnapshot 
    ): Observable<boolean> { 
     DEBUG.guard && debug('Guard FooPageGuard'); 

     return this._fooService.foo$().switchMap(
      foo => this._barService.getBar(foo) 
     ) 
     .map(data => { if (data) {return true} }) 
     .first() // Take first and enable the route 
     .do(foo => DEBUG.guard && debug('Guard OK FooPageGuard:', foo)) 

    } 
} 

스마트 구성 요소ActivatedRouteSnapshot 또는 RouteReuseStrategy

를 사용하여 완전히 필요성을 피할 수있는이 방법을 나는 것을 볼 수있었습니다 해결 방법 대신 감시 기능을 사용하면 상위 구성 요소의 렌더링이 한 번 실행됩니다. rs. 리졸버를 사용하면 동일한 렌더링 상태를 얻기 위해 여러 렌더링이 발생합니다. Angular 문서 보호자는 데이터 검색을위한 로그인 및 확인자에게 권장됩니다. 비동기식으로 많은 데이터 스트림을 처리해야하는 경우 많은 낭비적인 렌더링이 필요합니다.

그래서 질문입니다. 이 대회를 건너 뛰어도 괜찮습니까? ngrx state store subscription 및 resolver + ditching을 사용하여 데이터 요청을 트리거하는 가드를 위해 구성 요소에 subscription을 라우팅합니다.

또 다른 이상한 행동은 내가 처음에 무엇을해도 여전히 아이들의 컴피던스가 Init이되기 전에 observables에 의해 트리거되는 것으로 보이는 약간의 AppCmp 렌더링을 가지고 있다는 것입니다.

편집

난 그냥 오늘 몇 가지 문제가 있었다. 페이지 (스마트 구성 요소)와 같은 컨테이너 구성 요소에 OnPush을 사용하는 것은 실수였습니다. 구독은 시작되지만 템플릿은 업데이트 된 값을받지 않습니다. 입력이 트리거되지 않으므로 OnPush에서 예상됩니다. 따라서 OnPush는 벙어리 구성 요소에서만 사용하고 있으며, 이는 많은 노력을하기 때문에 여전히 중요한 개선 사항입니다.

편집 2 - 사용 리졸버하지 가드

... 예상대로이 작동하지 않았다. 관측자가 아직 해고하지 않았다면, 그 가드는 단순히 흐름을 영구적으로 막을 것이라고 말하자. 그래서 관측 가능한 것들이 이미 그 안에 들어있는 값들을 가지고 있기 때문에 멋진 예제가 효과가있었습니다. 철저한 정리를 한 후 내 앱이 작동하지 않는 것을 발견했습니다.

본질적으로 다음 기본 예제는 리졸버 내에서 작동하지만 가드에서는 작동하지 않습니다. 왜냐하면 관측 가능 대상은 그가 요청한 순간 다시 가치를 얻을 수 없기 때문에 관찰 할 수 없기 때문입니다. 나는 여분의 렌더링이 어디에서 오는 것인지 더 자세히 조사해야 할 것입니다. 어딘가에 결함이있는 코드가 있어야합니다.

return Observable.interval(1000) 
    .take(1) // Needed to trigger the guard. Resolvers do just fine without 
    .map(() => true) 
+1

제 생각으로 작동한다면 괜찮습니다. 추가하고자하는 유일한 방법은 fecthTheData와 같은 명명 된 메소드의 가드에 코드를 래핑하는 것이므로 다른 사람이 실제로 '가드 코드'가 아닌 것을 볼 수 있습니다. 그러나 해석자 코드와 가드 코드의 차이점은 무엇입니까? 해석자가 여러 번 호출 되는가? AOT를 사용하지 않을 때, 즉 AOT 특유의 해석자 '버그'가 발생하면 어떻게됩니까? –

+0

미리 빌드하면 각도 명령 행에서 이중 체크를 비활성화하는 데 도움이됩니다. 이후로 나는 webpack 설정을 꺼냈다. 나는이 방법을 선호한다. 이중 체크가 없으면 onlz에서 실제 렌더링을 볼 수 있습니다. 나는'fecthTheData'에 동의한다. 나는 그렇게 할 계획이었다. SOmehow 가드는 관찰이 완료 될 때까지 관찰 대상을 실행 한 다음 관찰 가능한 각 발사를 렌더링하는 해석자를 해제합니다. –

+0

그건 재미 있어요. switchMap은 관측 대상을 '중첩'하는 참신한 아이디어입니다 (나는 그곳에있는 이유라고 생각합니다). 저는 처음에 구독하고 다음 구독을 요청합니다. 물론 구독은 더 느립니다. 내 자신의 해결 코드를 보면, 왜 관측소가 다른 방식으로 동작하는지 생각할 수 없습니다. rxjs 항목은 다른 위치에서 일관되어야합니다. –

답변

0

사용 리졸버하지 가드

예상대로 음 ...이 작동하지 않았다. 관측자가 아직 해고하지 않았다면, 그 가드는 단순히 흐름을 영구적으로 막을 것이라고 말하자. 그래서 관측 가능한 것들이 이미 그 안에 들어있는 값들을 가지고 있기 때문에 멋진 예제가 효과가있었습니다. 철저한 정리를 한 후 내 앱이 작동하지 않는 것을 발견했습니다.

본질적으로 다음 기본 예제는 리졸버 내에서 작동하지만 가드에서는 작동하지 않습니다. 왜냐하면 관측 가능 대상은 그가 요청한 순간 다시 가치를 얻을 수 없기 때문에 관찰 할 수 없기 때문입니다. 나는 여분의 렌더링이 어디에서 오는 것인지 더 자세히 조사해야 할 것입니다. 어딘가에 결함이있는 코드가 있어야합니다.

return Observable.interval(1000) 
    .take(1) // Needed to trigger the guard. Resolvers do just fine without 
    .map(() => true)