2017-09-05 65 views
0

我想了解控制狀態窗口狀態之外的StatefulWidget狀態的最佳做法。從狀態控件外部控制狀態

我有下面的接口定義。

abstract class StartupView { 
    Stream<String> get onAppSelected; 

    set showActivity(bool activity); 
    set message(String message); 
} 

我想創建一個實現此接口的StatefulWidget StartupPage。我期望Widget執行以下操作:

  1. 當按下按鈕時,它會通過onAppSelected流發送事件。一個控制器甚至可以監聽它並執行一些操作(數據庫調用,服務請求等)。

  2. 控制器可以調用showActivityset message使視圖顯示消息的進度。

因爲有狀態的Widget不公開是國家作爲一個屬性,我不知道用於訪問和修改國家的屬性的最佳方法。

我希望用這種方式會是這樣的:

Widget createStartupPage() { 
    var page = new StartupPage(); 
    page.onAppSelected.listen((app) { 
     page.showActivity = true; 
     //Do some work 
     page.showActivity = false; 
    }); 
    } 

我想過通過傳遞,我希望它在createState()返回狀態實例化組件,但是,感覺錯了。

爲什麼我們有這種方法的一些背景:我們目前有一個Dart web應用程序。對於視圖控制器分離,可測試性和對Flutter的前瞻性思考,我們決定爲應用程序中的每個視圖創建一個接口。這將允許WebComponent或Flutter Widget實現此接口並保持所有控制器邏輯相同。

回答

2

您可以用靜態方法,幾撲例子做這種方式,我已經開始使用它,以及暴露狀態的小工具:

class StartupPage extends StatefulWidget { 
    static _StartupPageState of(BuildContext context) => context.ancestorStateOfType(const TypeMatcher<_StartupPageState>()); 

    @override 
    _StartupPageState createState() => new _StartupPageState(); 
} 

class _StartupPageState extends State<StartupPage> { 
    ... 
} 

然後,您可以通過調用訪問狀態StartupPage.of(context).doSomething();

這裏需要注意的是,你需要在樹的某個地方有一個BuildContext。

+0

如果這是一個合理的解決方案,讓StatefulWidget將它的狀態存儲在屬性中是否也是合理的? –

+0

問題在於'createState()'是一個由flutter調用的生命週期方法,所以你不應該自己調用它並存儲返回的狀態。 – xqwzts

+0

我用這種方法看到的問題是,它需要我們的通用控制器成爲Widget樹的一部分,這將違揹我們的設計目標,讓它們在Web上可重用。似乎Flutter強迫任何需要將小部件的狀態改變爲小部件本身的東西。 –