簡體   English   中英

Flutter bloc - 不要每次都調用api(在不同的視圖中使用相同的State)

[英]Flutter bloc - do not call the api every time (use the same State in different views)

我在我的顫振應用程序中使用顫振塊模式。 我有一個頁面中有幾個選項卡的底部導航欄。 其中兩個使用相同的 api 調用(相同的狀態)。 當用戶點擊其中一個時,我調用 api 來獲取數據,但是如果用戶點擊另一個選項卡,我想獲取數據而不再次調用 api。 我怎么能做到這一點?

在我的主頁(儀表板)中,我有 BlocBuilder 來更改選項卡,並在其中創建儀表板肘

class DashboardPage extends StatelessWidget {

 @override
 Widget build(BuildContext context) {
   return BlocBuilder<TabsBloc, AppTab>(
     builder: (BuildContext context, AppTab activeTab) {
       return Scaffold(
         appBar: AppBar(
           title: Text(DashboardHelpers.getTabLabel(activeTab)),
         ),
         body: RepositoryProvider(
           create: (BuildContext context) => DashboardRepository(),
           child: BlocProvider<DashboardCubit>(
             create: (BuildContext context) => DashboardCubit(
               dashboardRepository: context.read<DashboardRepository>(),
               authBloc: context.read<AuthBloc>(),
             ),
             child: DashboardHelpers.getTabContent(activeTab),
           ),
         ),
         bottomNavigationBar: TabSelector(
             activeTab: activeTab,
             onTabSelected: (tab) =>
                 BlocProvider.of<TabsBloc>(context).add(TabUpdated(tab))),
       );
     },
   );
 }
}

選項卡是作為子項加載的視圖。 其中一個視圖是 View1。 當我獲取我在 ContentView1 中加載的數據時

class View1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    BlocProvider.of<DashboardCubit>(context)..getDashboardDevices();
    return BlocConsumer<DashboardCubit, DashboardState>(
      listener: (BuildContext context, DashboardState state) {
        if (state is DashboardError) {
          showDialog(
            context: context,
            builder: (context) => AlertDialog(
              content: Text(state.message),
            ),
          );
        }
      },
      builder: (BuildContext context, DashboardState state) {
        if (state is DevicesLoaded) {
          return ContentView1(data: state.data);
        } else if (state is DashboardLoading) {
          return LoadingWidget();
        } else if (state is DashboardError) {
          return Container(
            child: Center(
              child: Text(state.message),
            ),
          );
        } else {
          return Container();
        }
      },
    );
  }
}

和 View2 幾乎一樣。 數據完全相同,並且加載到 ContentView2 中,但它是一個與 ContentView1 完全不同的小部件

class View2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    BlocProvider.of<DashboardCubit>(context)..getDashboardDevices();
    return BlocConsumer<DashboardCubit, DashboardState>(
      listener: (BuildContext context, DashboardState state) {
        if (state is DashboardError) {
          showDialog(
            context: context,
            builder: (context) => AlertDialog(
              content: Text(state.message),
            ),
          );
        }
      },
      builder: (BuildContext context, DashboardState state) {
        if (state is DevicesLoaded) {
          return ContentView2(data: state.data);
        } else if (state is DashboardLoading) {
          return LoadingWidget();
        } else if (state is DashboardError) {
          return Container(
            child: Center(
              child: Text(state.message),
            ),
          );
        } else {
          return Container();
        }
      },
    );
  }
}

問題是這兩個 VIEW 顯示來自同一個 API 端點的不同數據。 當用戶從 View1 切換到 View2 而不再次調用 API 時,如何加載已經獲取的數據。

謝謝!

你應該只調用getDashboardDevices()一次,因為你可以創建一個DashboardInitialState ,當用戶點擊一個選項卡時,如果狀態是DashboardInitialState你運行getDashboardDevices()而不是總是在構建視圖時。 這樣,當構建一個視圖時,您將只加載一次數據,並且它們都將在加載狀態下使用相同的數據。

以 View1 為例,嘗試使用兩個視圖:

class View1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocConsumer<DashboardCubit, DashboardState>(
      listener: (BuildContext context, DashboardState state) {
        if (state is DashboardError) {
          showDialog(
            context: context,
            builder: (context) => AlertDialog(
              content: Text(state.message),
            ),
          );
        }
      },
      builder: (BuildContext context, DashboardState state) {
        if(state is DashboardInitialState) {
          BlocProvider.of<DashboardCubit>(context)..getDashboardDevices();
          return LoadingWidget();
        } else if (state is DevicesLoaded) {
          return ContentView1(data: state.data);
        } else if (state is DashboardLoading) {
          return LoadingWidget();
        } else if (state is DashboardError) {
          return Container(
            child: Center(
              child: Text(state.message),
            ),
          );
        } else {
          return Container();
        }
      },
    );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM