成员 'notifyListeners' 只能在 'package:flutter/src/foundation/change_notifier.dart' 或测试中使用
The member 'notifyListeners' can only be used within 'package:flutter/src/foundation/change_notifier.dart' or a test
我正在使用 ChangeNotifier,我更改了它们的值并通知如下,
// Declare
ValueNotifier<bool> isDisplay = new ValueNotifier(false);
// Change value
isDisplay.value = false;
isDisplay.notifyListeners();
一切正常。但它会像下面那样发出警告,
我们能否通过适当的实施或其他方式解决此问题?
您不需要调用 notifyListeners
,因为它会在设置新值时自动调用。
ChangeNotifier
像 ValueListener
这样的实现永远不需要手动调用 notifyListeners
。
我也遇到了这些错误,更具体地说,是那些 2:
The member 'notifyListeners' can only be used within instance members of subclasses of 'package:flutter/src/foundation/change_notifier.dart'.dart(invalid_use_of_protected_member)
The member 'notifyListeners' can only be used within 'package:flutter/src/foundation/change_notifier.dart' or a test.dart(invalid_use_of_visible_for_testing_member)
经过一些研究,我得出了一些结论和解决方案。觉得我应该分享给遇到这个问题的人。
问题
实际上它说的很明显,“如果你想调用 notifyListeners()
,你必须在 ChangeNotifier 的子 class 或测试文件中执行它”
“但这是为什么呢?”可以理解,这是我的第二个问题。但在此之前,先了解一下 notifyListeners 方法到底是从哪里来的
notifyListeners 方法
如果您查看 ValueNotifier 的实现,它会扩展 ChangeNotifier class:
ChangeNotifier 有一个 notifyListeners()
方法(这就是我们首先可以使用此方法的原因)但不是通常的方式:
它受到保护。
@Dart 中的受保护注解 | doc
[@protected
annotation] Indicates that the annotated instance member (method, getter, setter, operator, or field) m in a class or mixin C should only be referenced in specific locations.
A reference from within the library in which C is declared is valid. Additionally, a reference from within an instance member in C, or a class that extends, implements, or mixes in C (either directly or indirectly), or a mixin that uses C as a superclass constraint is valid. Additionally, a reference from within an instance member in an extension that applies to C is valid.”
更通俗的解释:它可以用在子class中,直接扩展(或混入)ChangeNotifier
class 或在测试文件中。由于您想在您的逻辑代码中使用它,因此您必须执行本段的第一部分:“在您要调用 notifyListeners
方法的位置扩展或混合 ChangeNotifier。”
在哪里扩展(或混入)ChangeNotifier class?
您可能想在有状态或无状态小部件中使用它,并且由于 Dart 是 single-inheritance,您必须将 ChangeNotifier class“混合”到您的 class,但你错了。原因是 ChangeNotifier class 定义了它自己的 dispose
方法。由于 class 或混合到您的 class 的混合取代了以前继承的方法,现在您的 dispose
将是 ChangeNotifier 的 dispose
而不是国家的 dispose
.
记住,无论如何你都必须释放状态class使用的资源。如果你不在你的 State 中重写 dispose
方法,框架会为你做这件事,这很酷;但由于您刚刚更改了 dispose 方法的祖先,框架将不会触发所需的 dispose 方法。
因此,解决此问题的方法是,创建一个新的 class 来操纵值更改,并 扩展或混合 ChangeNotifier 到此 class。然后你可以随时随地调用 notifyListeners()
方法! (当然,不要调用 notifyListeners 除非你使用复杂的对象或发送相同的值)
此外,这些 class 最好称为 'Controller'、'ViewModel'、'BLoC' 或任何其他名称以表明它们是 mutating/controlling 你的价值观并触发 UI 在需要时重建。 (首先你应该做什么,将你的 UI 与你的逻辑层分开)。
进一步阅读
我正在使用 ChangeNotifier,我更改了它们的值并通知如下,
// Declare
ValueNotifier<bool> isDisplay = new ValueNotifier(false);
// Change value
isDisplay.value = false;
isDisplay.notifyListeners();
一切正常。但它会像下面那样发出警告,
我们能否通过适当的实施或其他方式解决此问题?
您不需要调用 notifyListeners
,因为它会在设置新值时自动调用。
ChangeNotifier
像 ValueListener
这样的实现永远不需要手动调用 notifyListeners
。
我也遇到了这些错误,更具体地说,是那些 2:
The member 'notifyListeners' can only be used within instance members of subclasses of 'package:flutter/src/foundation/change_notifier.dart'.dart(invalid_use_of_protected_member)
The member 'notifyListeners' can only be used within 'package:flutter/src/foundation/change_notifier.dart' or a test.dart(invalid_use_of_visible_for_testing_member)
经过一些研究,我得出了一些结论和解决方案。觉得我应该分享给遇到这个问题的人。
问题
实际上它说的很明显,“如果你想调用 notifyListeners()
,你必须在 ChangeNotifier 的子 class 或测试文件中执行它”
“但这是为什么呢?”可以理解,这是我的第二个问题。但在此之前,先了解一下 notifyListeners 方法到底是从哪里来的
notifyListeners 方法
如果您查看 ValueNotifier 的实现,它会扩展 ChangeNotifier class:
ChangeNotifier 有一个 notifyListeners()
方法(这就是我们首先可以使用此方法的原因)但不是通常的方式:
它受到保护。
@Dart 中的受保护注解 | doc
[
@protected
annotation] Indicates that the annotated instance member (method, getter, setter, operator, or field) m in a class or mixin C should only be referenced in specific locations.A reference from within the library in which C is declared is valid. Additionally, a reference from within an instance member in C, or a class that extends, implements, or mixes in C (either directly or indirectly), or a mixin that uses C as a superclass constraint is valid. Additionally, a reference from within an instance member in an extension that applies to C is valid.”
更通俗的解释:它可以用在子class中,直接扩展(或混入)ChangeNotifier
class 或在测试文件中。由于您想在您的逻辑代码中使用它,因此您必须执行本段的第一部分:“在您要调用 notifyListeners
方法的位置扩展或混合 ChangeNotifier。”
在哪里扩展(或混入)ChangeNotifier class?
您可能想在有状态或无状态小部件中使用它,并且由于 Dart 是 single-inheritance,您必须将 ChangeNotifier class“混合”到您的 class,但你错了。原因是 ChangeNotifier class 定义了它自己的 dispose
方法。由于 class 或混合到您的 class 的混合取代了以前继承的方法,现在您的 dispose
将是 ChangeNotifier 的 dispose
而不是国家的 dispose
.
记住,无论如何你都必须释放状态class使用的资源。如果你不在你的 State 中重写 dispose
方法,框架会为你做这件事,这很酷;但由于您刚刚更改了 dispose 方法的祖先,框架将不会触发所需的 dispose 方法。
因此,解决此问题的方法是,创建一个新的 class 来操纵值更改,并 扩展或混合 ChangeNotifier 到此 class。然后你可以随时随地调用 notifyListeners()
方法! (当然,不要调用 notifyListeners 除非你使用复杂的对象或发送相同的值)
此外,这些 class 最好称为 'Controller'、'ViewModel'、'BLoC' 或任何其他名称以表明它们是 mutating/controlling 你的价值观并触发 UI 在需要时重建。 (首先你应该做什么,将你的 UI 与你的逻辑层分开)。