【问题标题】:How to force UI "refresh" on nativescript (typescript) with Observables throught http requests?如何通过 http 请求强制使用 Observables 在 nativescript(打字稿)上“刷新”UI?
【发布时间】:2016-09-17 00:14:21
【问题描述】:

我正在使用带有模板语法的 TabView 组件对其进行迭代并在其中添加项目(使用可观察集合和异步管道)。我的项目来自一个 http 请求。

我的home.component.tns.html如下:

<ActionBar title="Angular 2 Seed Advanced (nativescript)">
</ActionBar>
<StackLayout>
  <TabView selectedIndex="0" selectedColor="#FF0000">
    <template ngFor let-tab [ngForOf]="tabs | async">
      <StackLayout *tabItem="tab">
          <Label text="tab item"></Label>
      </StackLayout>
    </template>
  </TabView>

  <Button text="call something" (tap)="emptymethod()"></Button>

</StackLayout>

...还有我的 home.component.ts:

...
    export class HomeComponent{

        public tabs: Observable<any[]>;

        constructor(private _menuService: MenuService) {

            this._menuService.getMenu()
                .map((menus) => {
                    let result: Array<any> = [];

                    if (menus) {
                        menus.forEach(menu => {
                            result.push({ 'title': menu.title });
                        });
                    }
                    return result;
                })
                .subscribe(
                data => {
                    this.tabs = Observable.of<any[]>(data);
                },
                error => error => this._log.debug(error));
        }

        emptymethod() {
            this._log.debug('HomeComponent - nada invoked');
        }

        ngOnInit() {

        }
    ...

当界面渲染时,TabView 菜单不会出现,但是当我点击 call something 按钮并调用 emptymethod 时,TabView 内的项目会出现,在换句话说,在“刷新”该组件后...

这不应该自动发生吗?

【问题讨论】:

    标签: typescript angular rxjs nativescript


    【解决方案1】:

    我在使用 nativescript 时遇到过几种情况,其中 UI 不会刷新(该区域不会触发 UI 刷新等),最简单的方法是强制代码运行到该区域中。这是一个小例子

    export class TestClass {
       constructor(private _ngZone: NgZone) {
       }
       someOperation(){
         this._ngZone.run(() => {
           //Do whatever you want here
         })
       }
    }
    

    我知道这不是最好的解决方案,但这是我认为目前最干净的解决方法

    这是我几个月前提出的另一个与此相关的问题:Angular 2 How to get Angular to detect changes made outside Angular?

    【讨论】:

      【解决方案2】:

      当涉及第三方插件时,在 nativescript-angular 中如何处理异步操作和更改检测似乎存在问题。

      目前的建议是将所有异步通知调用包装在一个分区回调函数中。

      以下视频解释了问题和解决方案。希望这可以帮助。 http://www.nativescriptsnacks.com/videos/2016/06/13/zoned-callbacks.html

      此处提供了有关 Nativescript 中相应功能请求的更多详细信息。 https://github.com/NativeScript/NativeScript/issues/2229

      【讨论】:

        【解决方案3】:

        我猜是因为在调用订阅中的next 块时没有触发更改检测,所以直到按下按钮触发更改检测时才会检测到对this.tabs 的更改。

        您应该能够简化您的 Observable 并且只需执行以下操作:

                this.tabs = this._menuService.getMenu()
                    //Convert the Array into a flattened Observable
                    .flatMap((menus) => menus ? menus.map(({title}) => {title}) : []);
        

        这将为您的 ngFor 块隐式地将数组展平为 Observable。

        【讨论】:

        • flatMap 是 Observables 的函数吗?我收到一条消息 flatMap in not a function ...或者我应该从 getMenu 返回一个数组而不是 Observable?
        • 是的flatMapObservable上的一个函数,它是mergeMap的别名。您可能需要导入它,请参阅here
        猜你喜欢
        • 2012-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-27
        • 1970-01-01
        • 2023-03-24
        • 2017-08-10
        相关资源
        最近更新 更多