Проблема
Мне кажется, то, что вы делаете, должно сработать. В прошлом я решал эту же проблему с асинхронным каналом и не сталкивался с какими-либо проблемами.
Поиск проблемы
Я написал небольшую утилиту, которая позволяет вам выходить из/входить в ngZone Angular в наблюдаемом объекте. Вы можете попробовать это, хотя мой опыт показывает, что вам не должно это понадобиться с асинхронным каналом.
Это более полезно, когда вы создаете длинные сложные преобразования и хотите создать (контролируемую) локальную мутацию, которая не запускает обнаружение угловых изменений.
Это довольно старое, так что вам может понадобиться настроить его? Точно сказать не могу.
// Inject ngZone
constructor(private ngZone: NgZone) { }
/*****
* Wrap every emission of an observable (next, complete, & error)
* With a callback function, effectively removing the invocation
* of these emissions from the observable to the callback.
*
* This isn't really too useful except for as a helper function for
* our NgZone Operators where we leverage this wrapper to run an
* observable in a specific JavaScript environment.
*****/
callBackWrapperObservable<T>(
input$: Observable<T>,
callback: (fn: (v) => void) => void
): Observable<T> {
const callBackBind = fn => (v = undefined) => callback(() => fn(v));
const bindOn = (ob, tag) => callBackBind(ob[tag].bind(ob));
return new Observable<T>(observer => {
const sub = input$.subscribe({
next: bindOn(observer, "next"),
error: bindOn(observer, "error"),
complete: bindOn(observer, "complete")
});
return { unsubscribe: () => sub.unsubscribe() };
});
}
ngZoneEnterObservable<T>(input$: Observable<T>): Observable<T> {
return this.callBackWrapperObservable(input$, this.ngZone.run.bind(this.ngZone));
}
ngZoneEnter<T>(): MonoTypeOperatorFunction<T> {
return this.ngZoneEnterObservable;
}
ngZoneLeaveObservable<T>(input$: Observable<T>): Observable<T> {
return this.callBackWrapperObservable(input$, this.ngZone.runOutsideAngular.bind(this.ngZone));
}
ngZoneLeave<T>(): MonoTypeOperatorFunction<T> {
return this.ngZoneLeaveObservable;
}
Вы можете попробовать это так:
В вашем .ts
:
items$ = ngZoneEnterObservable(
3rdPartyComponent.itemBehaviorSubject
);
or
items$ = 3rdPartyComponent.itemBehaviorSubject.pipe(
ngZoneEnter()
);
Тогда вместо 3rdPartyComponent.itemBehaviorSubject | async
можно просто написать items$ | async
Вы также можете использовать оператор tap
как быстрое и грязное средство для проверки того, сработала ли наблюдаемая
/***
* Curried function that logs the message (msg) and
* value (val)
***/
function logMsg(msg: string) {
return (val: any = null) =>
msg == null || msg.length < 1 ?
console.log(val) :
val == null ?
console.log(msg) :
console.log(`${msg}: `, val);
}
/***
* RxJS Pipeable Operator:
* Optionally prepend a message before logging
* the current value to the console.
***/
function log<T>(msg = ""): MonoTypeOperatorFunction<T> {
return pipe(tap(logMsg(msg)));
}
items$ = 3rdPartyComponent.itemBehaviorSubject.pipe(
log("Before ngZoneEnter"),
ngZoneEnter(),
log("After ngZoneEnter"),
);
person
Mrk Sef
schedule
25.05.2021
async
заключается в том, что он будет автоматически обрабатывать рендеринг. Вы всегда можете создатьsubcription
и избежать асинхронного канала, если хотите. - person StPaulis   schedule 25.05.2021Observable
из своегоBehaviorSubject
.Subscribe
на нем иconsole.log
выбросы. - person StPaulis   schedule 25.05.2021zone.js
— это сторонняя библиотека, которая генерирует асинхронные события и Angular, получает эти события и решает, когда выполнять рендеринг. Когда вы находитесь в компонентеOnPush
, только асинхронные каналы и изменения ввода заставляют компонент отображать. В противном случае рендеринг будет происходить после каждой асинхронной задачи или изменения. - person StPaulis   schedule 25.05.2021BehoviorSubject
на Observable, это сработает. В любом случае, вы можете заменить Subject фактическим значением, создав подписку. В следующий раз попробуй устроить стекблиц, это действительно поможет... - person StPaulis   schedule 25.05.2021.asObservable()
- person StPaulis   schedule 25.05.2021(3rdPartyComponent.itemBehaviorSubject | async)
и это сработало, то это НЕ BehaviorSubject, я думаю, вам нужно предоставить больше кода, чтобы мы могли помочь - person noririco   schedule 25.05.2021(3rdPartyComponent.itemBehaviorSubject.asObservable() | async)
Это не то, что я предлагаю. Я считаю, что вы должны закрыть тему на данный момент... - person StPaulis   schedule 25.05.2021