阿里云搭建自己的網(wǎng)站seo崗位是什么意思
? 場景:當(dāng)一個(gè)表單需要在表單全部或者特定項(xiàng)賦值后才會(huì)讓提交按鈕可點(diǎn)擊。
? 1.普通實(shí)現(xiàn)方式:
///場景:檢查[test11][test12][test13]均不為空時(shí)做一些事情,例如提交按鈕變成可點(diǎn)擊String? test11;String? test12;int? test13;///當(dāng)需要檢查[test11][test12][test13]是否全部有值時(shí)需要這么做。///1.給[test11][test12][test13]設(shè)置監(jiān)聽,或者在他們賦值的時(shí)候每次調(diào)用2檢查。///2.檢查三個(gè)值的狀態(tài)if(test11!=null&&test12!=null&&test12!=null){///print [test11][test12][test13]均不為空。}
? 2.使用Watcher方式實(shí)現(xiàn):
///使用[WatchableObject]配合[Watcher]監(jiān)測(cè)///1.只需要把String、int、bool、等對(duì)象用[WatchableObject]代替。WatchableObject test1 = WatchableObject();WatchableObject test2 = WatchableObject();WatchableObject test3 = WatchableObject();///2.使用[Watcher]單例綁定對(duì)象。Watcher().bindObject([test1, test2, test3]);///3.檢查回調(diào)Watcher().check((allCheck) {print("?????????????????????=$allCheck");});///4.模擬不同時(shí)間賦值Future.delayed(Duration(seconds: 3), () {test1.setValue("1");});Future.delayed(Duration(seconds: 6), () {test2.setValue("123");});Future.delayed(Duration(seconds: 8), () {test3.setValue(123);});///退出界面時(shí)清除Watcher使用得內(nèi)存@overridevoid dispose() {super.dispose();Watcher().clear();}
?logcat輸出:
方式1和方式2都能達(dá)到效果,但是方式1需要對(duì)每一個(gè)變量進(jìn)行監(jiān)聽,在每一個(gè)賦值的地方得檢查所有得值是否都已有了值,這樣實(shí)現(xiàn)的出錯(cuò)率就會(huì)變得很高。方式2則是利用變量托管,托管類已實(shí)現(xiàn)了對(duì)變量的賦值的監(jiān)聽,只要使用托管類WatchableObject包裝變量,則可以實(shí)時(shí)監(jiān)聽到變量的賦值變化,所以代碼上,對(duì)變量的使用不會(huì)再對(duì)變量進(jìn)行任何監(jiān)聽和處理,統(tǒng)一會(huì)由Watcher類進(jìn)行回調(diào)處理。方式1的缺點(diǎn)就是代碼混亂,容易出錯(cuò)。方式2的優(yōu)點(diǎn)可以解決方式1的缺點(diǎn),但是缺點(diǎn)是使用到Watcher的地方,變量必須交給WatchableObject托管,導(dǎo)致定義變量的時(shí)候變得麻煩,但是這個(gè)只要使用習(xí)慣了,確可以忽略該缺點(diǎn)。
喜歡這種方式的或者有需求用得到的朋友來擼代碼吧:
WatchableObject類:
import 'dart:math';import 'package:kq_flutter_widgets/widgets/listener/object_watcher/watcher.dart';
import 'package:kq_flutter_widgets/widgets/listener/object_watcher/watcher_callback.dart';///可觀察對(duì)象,
///[T]可觀察的對(duì)象類型。
///例如:傳入的是String,則會(huì)持有String對(duì)象,
///并可以設(shè)置[watcher]觀察綁定的String對(duì)象值的變化。
class WatchableObject<T> {T? _watchableObject;double? _uuid;///初始值WatchableObject({T? init}) {setValue(init);}///設(shè)置值void setValue(T? other) {_watchableObject = Watcher().value(getUuid(), other);}///設(shè)置觀察者void watcher(WatcherCallback watcherCallback) {Watcher().watcher(getUuid(), watcherCallback);}///獲取值T? value() {return _watchableObject;}///獲取uuiddouble getUuid() {return _uuid ??= Random().nextDouble();}
}
WatcherCallback類:
///回調(diào)
class WatcherCallback<T> {///值改變回調(diào)函數(shù),///[object]改變的值。final Function(T? object) onChanged;WatcherCallback(this.onChanged);
}
Watcher類:
import 'package:kq_flutter_widgets/widgets/listener/object_watcher/watchable_object.dart';
import 'package:kq_flutter_widgets/widgets/listener/object_watcher/watcher_callback.dart';///對(duì)象觀察者
class Watcher {Watcher._internal();factory Watcher() => _instance;static final Watcher _instance = Watcher._internal();final Map<double, WatcherCallback> _objectWatchers = {};final List<WatchableObject> _objects = [];final Map<double, bool> _bindObjects = {};///綁定對(duì)象,///[objects]綁定的一組對(duì)象。void bindObject(List<WatchableObject> objects) {clear();_objects.addAll(objects);for (WatchableObject str in objects) {_bindObjects.putIfAbsent(str.getUuid(), () => _checkObject(str.value()));}}///檢查綁定的對(duì)象是否已全部賦值,///[callback]每次賦值都會(huì)回調(diào),///[allCheck]是否全部已賦值,是則返回true,不是則返回false。void check<T>(Function(bool allCheck) callback) {for (WatchableObject str in _objects) {str.watcher(WatcherCallback((object) {_bindObjects.update(str.getUuid(),(value) => _checkObject(object),);_realCheck(callback);},),);}_realCheck(callback);}bool _checkObject<T>(T object) {return object is String ? object.isNotEmpty : object != null;}void _realCheck(Function(bool allCheck) callback) {bool isAllCheck = true;_bindObjects.forEach((key, value) {if (!value) {isAllCheck = false;return;}});callback.call(isAllCheck);}///清除內(nèi)存。void clear() {_objects.clear();_bindObjects.clear();_objectWatchers.clear();}///綁定回調(diào)執(zhí)行,///需要[WatchableObject]對(duì)象的[uuid]做為鍵值獲取對(duì)象綁定。T? value<T>(double uuid, T? other) {_objectWatchers[uuid]?.onChanged(other);return other;}///綁定設(shè)置,///需要[WatchableObject]對(duì)象的[uuid]做為鍵值,///[watcherCallback]綁定的回調(diào)。void watcher(double uuid, WatcherCallback watcherCallback) {_objectWatchers.putIfAbsent(uuid, () => watcherCallback);}
}