notifyDependents method
Notifies the dependents of a change.
The notification goes through didChangeDependencies, which can only run while a frame is being built. The only way left is therefore to mark the element dirty and notify the dependents from performRebuild.
Implementation
@protected
void notifyDependents() {
_notifyPending = true;
// Any build, not this element's own. `markNeedsBuild()` on an element that
// is building right now does nothing: the framework's assertion lets the
// self case through, and `if (dirty) return;` swallows the call. On an
// element that is *not* the one building, the same call is refused
// outright -- "setState() or markNeedsBuild() called during build" -- and
// that is what a model touched from the build of a descendant used to
// get. It is the same ordinary user code either way: a lazy load, a
// default filled in on first read. Asking for the rebuild after the frame
// is what turns a lost or refused notification into a late one.
if (_isRebuilding || SchedulerBinding.instance.isBuilding) {
// One callback while one is pending, not one per notification. The flag
// above is what the callback acts on, so a second notification arriving
// before the frame is over is already carried by the first, and a
// callback of its own would find nothing left to do.
if (_notifyDeferred) {
return;
}
_notifyDeferred = true;
SchedulerBinding.instance
// The build may be one `runApp` drives outside a frame, and then
// nothing has asked for the frame this callback needs.
..scheduleFrame()
..addPostFrameCallback((_) {
_notifyDeferred = false;
if (mounted && _notifyPending) {
markNeedsBuild();
}
});
} else {
markNeedsBuild();
}
}