簡體   English   中英

Flutter:如何從 api 獲取數據一次並用於不同的屏幕

[英]Flutter: How to fetch data from api once and use for different screen

如何獲取數據,例如在一個屏幕中獲取一次用戶詳細信息並在另一個屏幕中使用它?

我想獲取一次數據,我可以在另一個屏幕中使用該數據而無需再次獲取。 謝謝你。

您可以嘗試使用共享首選項來存儲數據並在每次要使用它時檢索它

如果我理解您的問題,您知道如何獲取用戶詳細信息,但不想多次加載它,而是使用來自不同小部件的數據。

共享首選項可以工作,但我不推薦它,它僅用於存儲原始數據。

一個簡單但並不完美的解決方案是創建一個應用程序級別的單例類。 您可以加載/更新用戶詳細信息,並且可以從應用程序的任何地方訪問它。 就像是:

class UserDetails {
   // define every member data here that you will load
   static late String name;
   static late String email;
   
   // this makes it singleton-like
   factory UserDetails() => UserDetails._internal();
   UserDetails._internal();
}

您可以設置/獲取用戶詳細信息,例如:

UserDetails.name

一種更類似於 Flutter 的方法是將用戶詳細信息視為應用程序的狀態,並使用通知程序在整個小部件樹中“廣播”這些值。 一個好的起點是閱讀文檔中的這一部分

這是一個非常簡單的示例,如何從 API 加載數據並將數據存儲在單例類中 該示例僅限於一個數據(電子郵件),但您當然可以擴展它。 在現實世界的應用程序中需要大量的錯誤處理,這個例子假設一切都很好:

class UserDetails {
  static late String email;

  factory UserDetails() => UserDetails._internal();
  UserDetails._internal();

  static Future<void> getUserDetails() async {
    // API_BASE_URL for example: "domain.com"
    // API_URL for example: "/user/details"
    // AUTHORIZATION: optional, skip headers part if you don't need
    final response = await http.get(
        Uri.https(API_BASE_URL, API_URL),
        headers: {'authorization': AUTHORIZATION});

    // here we decode the response body, assuming
    // that data is under "data" tag in response JSON
    final responseData = jsonDecode(response.body)["data"];

    // and within it we have an "email" tag with the user's mail
    // here 'email' is the static member of this class
    // and we set the value from the API response
    email = responseData["name"];
  }
}

請注意,為簡單起見,沒有錯誤處理 我們甚至不檢查響應的狀態代碼是否為 200。(您可以輕松添加它,提示: response.statusCode 包含它。)此外,其他事情可能會出錯,服務器中斷等。

好的,那么如何加載數據並訪問它呢? 函數getUserDetails是異步的,所以在你的代碼中的某個地方(我猜是早期的某個地方)你必須從另一個異步函數調用它一次,以便你可以等待它。 確保找到一個不會再次運行的地方,並使用調試控制台進行檢查! 以下行將從 API 獲取數據並將其存儲在靜態成員中:

await UserDetails.getUserDetails();

如果這樣做,您可以從應用程序的任何位置讀取和寫入從您的 API 加載的用戶詳細信息,而無需重新加載它:

print(UserDetails.email);
UserDetails.email = "new email";

在其他文件中編寫您的 API 函數,請參見下文:

Future apiCall() async {
  var url = 'put your API url here';
  var result = await http.get(url);
  if (result.statusCode == 200) {
    return json.decode(result.body);
  } else {
    throw Exception('Failed');
  }
}

然后在調用以下 API 時調用其他文件中的 API 函數:

FutureBuilder(
      future: apiCall(),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          if (snapshot.data.length > 0) {
            return Text(
              
                  '${snapshot.data[0]['name']}'
                  
              style: TextStyle(
                fontWeight: FontWeight.bold,
                wordSpacing: 200,
                fontSize: 20,
              ),
             
            );
          } else {
            return Text(
              '❌ No Data Found',
              style: TextStyle(
                color: Colors.red,
              ),
            );
          }
        }
        return CircularProgressIndicator();
      },
    ),

暫無
暫無

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

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