Nativescript ActivityIndicator неправильно слушает занятую = переменную - PullRequest
0 голосов
/ 02 марта 2019

я создаю небольшое приложение, в котором я хочу, чтобы при каждом запросе на сервер я получал ActivityIndicator.

Итак, в моей службе пользовательского интерфейса у меня есть Тема, и я слушаю ее в своем ActivityIndicatorComponent.Результат: он начинает "занято", но не останавливается, даже если переменная в атрибуте индикатора "занято" имеет значение false.

То есть идентификатор как-то "не обновляется" после однократной инициализации?

My UIService

    @Injectable({ providedIn: 'root'})
export class UiService {
    private _drawerState=  new BehaviorSubject<void>(null);
    isLoading = new Subject<boolean>();

    get drawerState() {
        return this._drawerState.asObservable();
    }

    toggleDrawer() {
        this._drawerState.next(null);
    }

    setIsLoading(value: boolean) {
        this.isLoading.next(value);
    }

}

My Socket Service, который вызывает метод в Ui Service:

export class SocketioService {
socket;

currentRoom: ChatRoom;
message_receiver = new Subject<Message>();
room_receiver = new Subject<ChatRoom>();


constructor(private router: RouterExtensions, private ui: UiService) {
    this.socket = SocketIO.connect("http://localhost:3000");
    console.log("SOCKET: " + this.socket);

    this.socket.on("chat room", (room) => this.onReceivingChatRoom(room));

}


onRequestRoomlist(data) {
    this.ui.setIsLoading(true);
    this.socket.emit("request rooms", data);
}

onReceivingChatRoom(room) {
    this.ui.setIsLoading(false);
    console.log("Received Chat Room");
    this.room_receiver.next(new ChatRoom(room.name, room.description, room.image, room.protection));
}
}

И, наконец, я слушаю тему в моем ActivityIndicatorComponent:

export class ActivityIndicatorComponent implements OnInit {

  isLoading: boolean;

  constructor(private ui: UiService) { }

  ngOnInit() {
    this.ui.isLoading.subscribe(
        (value: boolean) => {
          this.isLoading = value;
        }
    )
  }

}

Вот XML-код компонента ActivityIndicatorComponent

<ActivityIndicator #indicator row="1" col="1" width="50" height="50" busy="{{isLoading}}" color="#6495ed"></ActivityIndicator>

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Сокет, вероятно, работает за пределами угловой зоны, поэтому при изменении переменной он отправляет обновление субъекту и, поскольку он находится за пределами зоны, не вызывает обнаружение изменений.

Это можно исправитьдвумя способами:

  1. Как вы уже исправили, вручную набрав detectChanges()
  2. Запустив внутри угловой зоны с помощью ngZone.run(() => {/* code */});

Вы можететакже используйте этот наблюдаемый оператор, чтобы обеспечить выполнение кода внутри зоны.

import { NgZone } from '@angular/core';
import { Observable } from 'rxjs/Observable';

export function enterZone(zone: NgZone) {
  return <T>(source: Observable<T>) =>
    new Observable<T>(observer =>
      source.subscribe({
        next: (x) => zone.run(() => observer.next(x)),
        error: (err) => observer.error(err),
        complete: () => observer.complete()
    })
   );
}

Таким образом, вы можете использовать: this.ui.isLoading.pipe(enterZone(ngZone)).subscribe().Или, что еще лучше, вы можете определить в своей службе:

isLoading$ = this.isLoading.pipe(enterZone(ngZone))

Таким образом, вы уверены, что все, что подписывается на isLoading$, действительно работает внутри угловой зоны.

Редактировать:

Пример службы UIS с наблюдаемой:

@Injectable({ providedIn: 'root'})
export class UiService {
    private _drawerState=  new BehaviorSubject<void>(null);
    isLoading = new Subject<boolean>();
    isLoading$ = this.isLoading.pipe(enterZone(this.ngZone));

    get drawerState() {
        return this._drawerState.asObservable();
    }

    constructor(private ngZone: NgZone) {}

    toggleDrawer() {
        this._drawerState.next(null);
    }

    setIsLoading(value: boolean) {
        this.isLoading.next(value);
    }

}
0 голосов
/ 02 марта 2019

Я исправил это, используя ChangeDetectorRef в ActivityIndicatorComponent.

После получения нового значения через подписку, которую я назвал changeRef.detectChanges();, она работает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...