Reputation: 81
when I use Getx
to update my Widget?
I do not know Rx()
how to contact to the thing I put in.
code is _obx=Rx()
.
but I send data is "".obs
. that is not Rx()
but this is RxString()
.
when I use "".obs.value="newString"
. why Rx()
can know that who updates data.
just like :
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class GetIncrementPage extends StatefulWidget {
GetIncrementPage({Key key}) : super(key: key);
@override
_GetIncrementPageState createState() => _GetIncrementPageState();
}
class _GetIncrementPageState extends State<GetIncrementPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('get'),
),
body: Container(
alignment: Alignment.center,
child: _body(),
),
);
}
Widget _body() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
OutlineButton(
child: Text('get 数字加减'),
onPressed: c.increment,
),
OutlineButton(
child: Text('get log 变化'),
onPressed: c.change,
),
Obx(() {
printInfo(info: '刷新了页面 get_example');
return Text(c.count.toString());
}),
ObxValue((v) {
printInfo(info: '刷新了页面 get_ObxValue_log1 ');
return Text('logValue:' + v.toString());
}, ObjectKey('key').obs),
Obx(() {
printInfo(info: '刷新了页面 get_obx_log1');
return Text('logObx:' + c.log.toString());
}),
Obx(() {
printInfo(info: '刷新了页面 get_obx_log2');
return Text(c.log2.toString());
}),
// ObxValue((var value) => Text('${value.toString()}'), c),
],
);
}
@override
void dispose() {
Get.delete<Controller2>();
super.dispose();
}
final Controller2 c = Get.put(Controller2());
}
///
/// Created by fgyong on 2020/10/22.
///
class Controller2 extends GetxController {
var count = 0.obs;
var count2 = 0.obs;
final log = ''.obs;
final log2 = ''.obs;
increment() => count++;
@override
void onClose() {
printInfo(info: 'Controller close');
super.onClose();
}
void change() {
log.value += ' ${log.value.length}';
}
}
when i change log.value to new String,why log2 do not fresh.
class Obx extends StatefulWidget {
final WidgetCallback builder;
const Obx(this.builder);
_ObxState createState() => _ObxState();
}
class _ObxState extends State<Obx> {
RxInterface _observer;
StreamSubscription subs;
_ObxState() {
_observer = Rx();
}
@override
void initState() {
subs = _observer.subject.stream.listen((data) => setState(() {}));
super.initState();
}
@override
void dispose() {
subs.cancel();
_observer.close();
super.dispose();
}
Widget get notifyChilds {
final observer = getObs;
getObs = _observer;
final result = widget.builder();
if (!_observer.canUpdate) {
throw """
[Get] the improper use of a GetX has been detected.
You should only use GetX or Obx for the specific widget that will be updated.
If you are seeing this error, you probably did not insert any observable variables into GetX/Obx
or insert them outside the scope that GetX considers suitable for an update
(example: GetX => HeavyWidget => variableObservable).
If you need to update a parent widget and a child widget, wrap each one in an Obx/GetX.
""";
}
getObs = observer;
return result;
}
@override
Widget build(BuildContext context) => notifyChilds;
}
Why can rx() establish contact with the log, please help me. When I update How can Rx() know when logging?
just help me.
Upvotes: 7
Views: 94253
Reputation: 81
see link https://github.com/jonataslaw/getx/issues/937,
when Obx()
build,we named it ObxA
, named "ABC".obs abcobs
,
in Obx
Widget get notifyChilds {
final observer = getObs;
getObs = _observer;
final result = widget.builder();
if (!_observer.canUpdate) {
throw """
[Get] the improper use of a GetX has been detected.
You should only use GetX or Obx for the specific widget that will be updated.
If you are seeing this error, you probably did not insert any observable variables into GetX/Obx
or insert them outside the scope that GetX considers suitable for an update
(example: GetX => HeavyWidget => variableObservable).
If you need to update a parent widget and a child widget, wrap each one in an Obx/GetX.
""";
}
getObs = observer;
return result;
}
when build,RxString()
will execute get value
,and addListen()
:
code is
set value(T val) {
if (_value == val && !firstRebuild) return;
firstRebuild = false;
_value = val;
subject.add(_value);
}
/// Returns the current [value]
T get value {
if (getObs != null) {
getObs.addListener(subject.stream);
}
return _value;
}
void addListener(Stream<T> rxGetx) {
if (_subscriptions.containsKey(rxGetx)) {
return;
}
_subscriptions[rxGetx] = rxGetx.listen((data) {
subject.add(data);
});
}
so They made a connection
Upvotes: 1
Reputation: 28010
You can use Obx
or GetX
widgets from Get to "listen" to changes to observable variables you declare in a GetxController.
I think you are also confusing Rx as an ObserVER vs. ObservABLE. Rx is an observable, i.e. you watch it for changes using Obx or GetX widgets, (I guess you can call these two widgets "Observers".)
class Log2Page extends StatelessWidget {
@override
Widget build(BuildContext context) {
Controller c = Get.put(Controller());
// ↑ declare controller inside build method
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Obx(
() => Text('${c.log2.value}')
),
RaisedButton(
child: Text('Add +1'),
onPressed: c.change,
)
],
),
),
),
);
}
}
class Controller extends GetxController {
RxInt log2 = 0.obs;
void change() => log2.value++;
}
obs
, like count.obs
and log2.obs
. When you want to "listen" or "observe", use Obx
or GetX
widgets. These automatically listen to obs
changes of its child and rebuild when it changes.class Log2Page extends StatelessWidget {
@override
Widget build(BuildContext context) {
Controller c = Get.put(Controller());
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Obx(
() => Text('Obx: ${c.log2.value}')
),
// ↓ requires manual controller.update() call
GetBuilder<Controller>(
builder: (_c) => Text('GetBuilder: ${_c.log2.value}'),
),
// ↓ controller instantiated by Get widget
GetX<Controller>(
init: Controller(),
builder: (_c) => Text('GetX: ${_c.log2.value}'),
),
RaisedButton(
child: Text('Add +1'),
onPressed: c.change,
),
RaisedButton(
child: Text('Update GetBuilder'),
onPressed: c.update, // rebuild GetBuilder widget
),
],
),
),
),
);
}
}
class Controller extends GetxController {
RxInt log2 = 0.obs;
void change() => log2.value++;
}
Listens to observable (obs
) changes. Controller needs to already be declared/initialized elsewhere to use.
Listens to observable (obs
) changes. Can initialize controller itself using init:
constructor argument, if not done elsewhere. Optional argument. Safe to use init:
if Controller already instantiated. Will connect to existing instance.
Does not listen to obs
changes. Must be rebuilt manually by you, calling controller.update()
. Similar to a setState()
call. Can initialize controller itself using init:
argument, if not done elsewhere. Optional.
Upvotes: 44
Reputation: 375
First:
when I "".obx.value="newString".why Rx() can know.
This is wrong, the .obx doesn't exist, I guess you mean .obs;
When you create a OBS variable like: final a = ''.obs
, the type of this var will be a RxString(), so you can use to observer this var whatever you want to.
I know two widgets can you use to observer in your screen:
GetX(), Obx()
Upvotes: 0