flutter_modular 7.1.1
flutter_modular: ^7.1.1 copied to clipboard
Smart project structure with dependency injection and route management for Flutter.
Changelog #
7.1.1 #
- Fix: feature modules reached through a
RouterOutletnow get their binds. The outlet keeps its own sub-stack but never reported its entries to the module manager, so a feature mounted as a child of a shell (e.g./with aRouterOutletbody) failed with "X not registered" when navigated to inside the outlet. Outlet entries now activate and release their feature modules on push, navigate, replace, pop and dispose, just like root stack entries.
7.1.0 #
- Feature modules can now consume shared/core dependencies directly. A
module-level bind inside a feature (a module with a
path) —addSingleton,add,addLazySingleton— now resolves dependencies registered in a root-owned shared module (a path-lessmodule(...), the "core"). Previously only page-scopedprovidebinds could reach the core; a feature's module-level binds ran in a leaf injector that couldn't see root-owned binds, forcing shared deps to be threaded in by hand. This removes that asymmetry: a core consumer can be aprovide, the core itself, OR a feature module-level bind — all alike. A feature's own bind still shadows a same-typed core bind (local wins; core is the fallback). - Requires
auto_injector >= 2.2.0, which adds the opt-in upward resolution (addInjector(child, resolveUpward: true)) this builds on, fixes a dispose-listener accumulation in its layer graph, and adds anUpwardResolutionCycleguard against mutual upward links.
7.0.3 #
- Customizable route transitions.
route(transition:)and the new app-wideModularApp(defaultTransition:)now accept anyPageTransition, an open contract that builds the route'sPage. Three ways to supply one:- the
TransitionTypepresets (material,fade,none) — each value now is aPageTransition, so existingtransition: TransitionType.fadekeeps working; CustomTransition— the inline convenience: pass atransitionsBuilder(same signature asPageRouteBuilder) and optionally tuneduration/reverseDuration/opaque/barrierColor/barrierDismissible/fullscreenDialog; Modular still owns thePage;- implement
PageTransitionyourself for full control of thePage(e.g. aCupertinoPagewith swipe-back, afullscreenDialog, shared-axis from theanimationspackage).
- the
- App-wide default.
ModularApp.defaultTransition(defaultTransitionType.material) applies to every route that doesn't declare its own. Precedence: route-local → app default →material.route(transition:)now defaults tonull(inherit the app default) instead of forcingmaterial.
7.0.2 #
context.select<T, R>(selector)— the method-based twin of theSelectorwidget. Reads a value derived from a page-scopedTand rebuilds the calling widget only when the selected value changes (==). Mirrorscontext.selectfromproviderto ease migration; call it frombuild.
7.0.1 #
- Page-scoped BLoC/Cubit support. New
Scoped.addStreamable<T>(ctor, (t) => t.stream, (t) => t.close())exposes the object itself viacontext.watch<T>()(read its synchronousstate, call its methods) while rebuilds are driven by its stream — flutter_modular keeps no dependency on theblocpackage (stream/close are caller callbacks). CompanionaddListenable<T>(ctor, (t) => t.listenable, (t) => t.dispose())for objects whose reactivity is aListenableproperty. See the docs for a suggestedaddBlocextension covering both BLoC and Cubit. add<T>(ctor)— non-reactive page-scoped object, readable viacontext.read/watchand disposed on unmount when it implementsDisposable. Breaking: replacesaddDisposable, which is removed (theDisposableinterface is retained).addChangeNotifierreexpressed overaddListenable;watch/read/Consumer/Selectornow accept anyObject(not justListenable), so a non-Listenablereactive object can be exposed.
7.0.0-dev.1 #
Ground-up rewrite of flutter_modular. Breaking: the v6 API (Module with
List<Bind> get binds / List<ModularRoute> get routes, Bind, ChildRoute,
ModuleRoute, the global Modular facade, and the modular_core engine) is
replaced. v7 is a single, self-contained Flutter package (depends directly on
auto_injector + web; modular_core is gone).
- Modules are DI + Routes only, declared functionally with
createModule(register:)and a flatModularContext(addSingleton/add*,route(path, child:, provide:, children:, guards:, transition:),module(value, {at})to include shared deps or mount submodules). Deduped by identity; path-less modules are root-owned (shared), path-bearing modules are features with their own DI lifecycle (bound on first route entry, disposed on last exit). - Navigator 2.0, fully declarative: hierarchical route matching with
/:params,RouterOutletfor persistent shells with their own nested stack, guards/redirects, transitions.context.pushNamed/navigate/replace/pop(+popUntil/popAndPushNamed/pushNamedAndRemoveUntil). URL mirrors the stack base; pushes stay out of the URL by design. Relative routes resolve against the current location. - Page-scoped state via
provide:addChangeNotifier/addStream/addDisposablebuild state 1:1 with the view in a page-local injector and dispose it when the route leaves. Read withcontext.watch/read/selectand theConsumer/Selectorwidgets. App-scoped state goes onModularApp(provide:)(aboveMaterialApp). context.routeState()— reactive access to the currentRouteState(uri + resolved params + arguments) for route-aware chrome.inject<T>()for runtime resolution where a constructor can't inject (e.g. route guards).
See example/ for a complete app exercising every feature.