1

관찰 가능한 개체의 속성을 업데이트해야합니다. 나는 그럭저럭 일하게 할 수 있었다. 그러나 나는 내가 그것을했던 방법을 정말로 좋아하지 않는다. 이 경우 filter$ 값 개체를 업데이트 할 수있는 더 우아한 방법은Observable/BehaviorSubject를 코드에서 업데이트하는 방법은 무엇입니까?

next(filter$: BehaviorSubject<GridCollectionFilter>, collection: GridCollectionModel<any>) { 
    let filter = filter$.value; 

    if (!filter.page) { 
    filter.page = 1; 
    } 

    filter.page++; 

    if (filter.page > collection.pageCount) { 
    filter.page = collection.pageCount; 
    } 

    this.updateFilter(filter$); 
} 

first(filter$: BehaviorSubject<GridCollectionFilter>) { 
    filter$.value.page = 1; 
    this.updateFilter(filter$); 
} 

last(filter$: BehaviorSubject<GridCollectionFilter>, collection: GridCollectionModel<any>) { 
    filter$.value.page = collection.pageCount; 
    this.updateFilter(filter$); 
} 

updateFilter(filter$: BehaviorSubject<GridCollectionFilter>, filter?: GridCollectionFilter) { 
    filter$.next(_.clone(filter || filter$.value)); 
} 

있습니까?

filter$.next(_.clone(filter$.value)) 내가 코드를 통해 관찰 된 개체의 몇 가지 속성을 단순히 업데이트하려고 할 때마다 관찰 대상의 복제본을 개로 먹이는 아이디어를 정말 싫어합니다. 참조를 깨기 위해 _.clone()을 사용하고 있습니다. 그렇지 않으면 명백한 이유 때문에 rxjs distinctUntilChanged()이 트리거되지 않습니다.

내가하고있는 일을 줄여 줄 수있는 rxjs 확장이 있습니까? 나는 내부적으로 filter$.next(_.clone(filter$.value))을 할 filter$.commitValueChanges() 줄을 따라 생각하고 있습니다.

저는 처음부터 완전히 잘못된 방식으로 이것을 생각하고 있는지 잘 모르겠다. 변경 청취자를 트리거하려고 할 때 새로운 상태를 적용해야한다는 것을 이해합니다. 확실하지 않은 점은 필터 $ .value를 직접 수정해야하는지 여부입니다. 또는 일반적으로 filter (필터)과 filter$ (필터를 관찰 할 수 있음)이라는 두 개체가 있고 그 다음에 filter이 변경 될 때마다 filter.next()으로 제출하면됩니다. 그러나 이제는 두 개의 객체가 있는데, 이는 응용 프로그램을 통해 변경 중이며 다양한 이벤트 핸들러를 연결하여 수동으로 처리해야하는 객체와 다른 객체를 업데이트 할 수있는 객체 인 - filter$을 가지고 있기 때문에 중복되는 것처럼 보일 것입니다. 그것은 나에게 과도하고 해커처럼 보입니다.

Thnx.

답변

1

코드에서 _clone()을 제거하려면 distinctUntilKeyChanged()를 사용해야합니다. 객체의 키가 변경되었는지 여부를 확인합니다.

DistinctUntilKeyChanged API

그러나 더 나은 aproach는 다음과 같습니다

filter$: BehaviorSubject<GridCollectionFilter>; 
collection: GridCollectionModel<any>; 
currentFilter: GridCollectionFilter; 

ngOnInit() { 
    this.filter$.subscribe(filter => { 
    this.currentFilter = filter; 
    // Here for example invoke rest api with filter to change collection 
    }) 
} 

next() { 
    if (!this.currentFilter.page) { 
    this.currentFilter.page; 
    } 

    this.currentFilter.page++; 

    if (this.currentFilter.page > this.collection.pageCount) { 
    this.currentFilter.page = collection.pageCount; 
    } 

    this.filter$.next(this.currentFilter); 
} 

first() { 
    this.currentFilter.page = 1; 
    this.filter$.next(this.currentFilter); 
} 

last(filter$: BehaviorSubject<GridCollectionFilter>, collection: GridCollectionModel<any>) { 
    this.currentFilter.page = collection.pageCount; 
    this.filter$.next(this.currentFilter); 
} 
+1

나는 'distinctUntilKeyChanged()'비트를 좋아하는데, 그것은 매우 도움이된다. 나는 그것을 인식하지 못했다. 하지만 추가적인 복잡성을 추가하고 코드를 중복하여 추가 currentFilter 필드를 추가하는 것은 큰 팬이 아닙니다. 나는 두 개의 필터 객체를 가지지 않으려 고하고 있는데, 단 하나의 트릭을 수행 할 수 있어야한다는 의견이 있습니다. 그들 중 두 명은 해커와 지저분한 느낌을 갖습니다. – pootzko

+0

붙여 넣은 메서드는 실제로 서비스 클래스에 있지만 구성 요소에는 없습니다. 'filter $'observable은 커스텀'BaseGridComponent'에 의해 만들어진 무언가이며 이벤트 핸들러 메쏘드 (다음에 붙여 넣지 않은 첫 번째와 다른 것들)는'filter $'를 업데이트해야합니다. 말이된다. 'filter $ .value'는 관찰 된 것이고, 그것이 바뀔 때, 필터 객체는 백엔드로 전송되어 데이터를 가져옵니다. – pootzko

+0

그래서 그것을 BaseGridComponent 컴포넌트로 이동하십시오. BaseGridComponent로 확장 한 그리드에서 필터 변경을 수신 한 다음 rest API를 호출하여 콜렉션을 다시로드합니다. 어떻게 생각하니? – pioro90

0

유일한 문제는 당신이 어쩌면 이러한 팁 중 하나가 당신을 도울 것입니다 개체를 복제 할 필요가있는 경우 :

  • distinctUntilChanged 연산자는 기본적으로 개체 ID를 비교합니다. 그러나 원하는 비교 로그인을 구현하는 데 사용할 수있는 선택적인 compare 기능이 필요합니다.

    .distinctUntilChanged((a, b) => a.page === b.page) 
    

    그냥 얕은 복사본을 만드는 확인을 경우 당신이이 중 하나를 사용할 수 있습니다 당신은 또한 동일한 속성

    .distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)) 
    
  • 으로 서로 다른 두 인스턴스를 비교하는 데 사용할 수 있습니다 :

    Object.assign({}, filter) 
    

    또는이 :

    { ...filter } 
    

    두 가지 모두 얕은 사본입니다.

    JSON.parse(JSON.stringify(filter)) 
    

    이 방법을 당신이 어떤 제 3 자 필요하지 않습니다 : 당신이 깊은 사본이 필요하고 성능에 대해 걱정하지 않은 경우

  • 당신은 JSON을 사용할 수 있습니다 (당신은 매우 작은 물체를 가지고있는 것처럼 보인다) 도서관.

+1

사실 복제품 일뿐입니다. '_.clone()'(그리고 일반적으로 lodash)을 가지고 있어도 괜찮습니다. 왜냐하면 매우 유용한 lib이기 때문에 모든 앱에서 기본적으로 가지고 있기 때문입니다. '.next()'를 복제 된 관찰 가능 값으로 먹이면 속성 또는 두 가지를 업데이트하는 것과 같은 단순한 오버 헤드가 생기는 것 같습니다. '.nextSelf()'라는 간단한 메소드를 사용하면 코드의 양이 줄어들 것이라고 생각합니다. 그러나 판단을 내리기 전에 관측 가능성을 좀 더 연구해야합니다. 지금 당장은 조금 단순화 할 방법을 찾고 있습니다. – pootzko

+0

당신의 코드가 무엇을해야하는지 이해할 수 없다고 생각합니다. – martin

+1

내 질문에 대해 너무 많은 소음이 들릴 것이라고 생각했기 때문에 모든 것을 지루하게하고 싶지 않았습니다. 나는'filter $ .next (_ .clone (filter $ .values)) '에 대한 필요성을 대체 할 일종의'filter $ .commitValueChanges()'가 있는지 궁금 할 뿐이다. 내 질문을 조금 업데이트하겠습니다. 어쨌든 대답을 작성해 주셔서 감사합니다. – pootzko

0

정확히 무슨 문제가 있는지, 나는 정확히 동일한 문제로 고심하고 있습니다. 필자는 피검자의 가치를 직접 수정했기 때문에 다양한 각도 변화 감지 문제에 부딪 혔습니다. 이제 막 _cloneDeep 값을 수정 한 다음 .next()를 사용하여 대상으로 다시 피드합니다. 나도 주제가 변화를 감지하고 새로운 대상을 발표 할 수있는 일종의 지름길에 감사 할 것이다. 당분간 더 나은 해결책을 찾지 못했습니다.