Skip to content

Signals

Stefan Wurzelsand edited this page Jun 2, 2026 · 6 revisions

Signals

Einfacher Counter mit globalem Signal

import 'package:flutter/material.dart';
import 'package:signals_flutter/signals_flutter.dart';

final counter = signal(0);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Signals with Global Signal')),
        body: Center(
          child: SignalBuilder(builder: (context) => Text('Value: $counter')),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () => counter.value++,
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

Signals mit Service Locator GetIt

import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:signals_flutter/signals_flutter.dart';

// --- DATA LAYER ---
class WeatherRepository {
  Future<String> fetchWeatherFromServer(String city) async {
    await Future.delayed(const Duration(seconds: 1));
    return '21°C, leicht bewölkt in $city';
  }
}

// --- LOGIC LAYER ---
class WeatherController {
  final WeatherRepository _repository;
  WeatherController(this._repository);

  final weatherData = signal<String?>(null);
  final isLoading = signal<bool>(false);

  Future<void> loadWeather(String city) async {
    isLoading.value = true;
    try {
      final result = await _repository.fetchWeatherFromServer(city);
      weatherData.value = result;
    } catch (e) {
      weatherData.value = 'Fehler beim Laden';
    } finally {
      isLoading.value = false;
    }
  }
}

// --- DEPENDENCY INJECTION ---
final di = GetIt.instance;

void setupArchitecture() {
  di.registerLazySingleton(() => WeatherRepository());
  di.registerLazySingleton(() => WeatherController(di<WeatherRepository>()));
}

// --- MAIN START ---
void main() {
  // Zwingt die Flutter-Engine zur korrekten Initialisierung vor dem Isolat-Start
  WidgetsFlutterBinding.ensureInitialized();

  // 1. Diese Zeile schaltet die automatischen Konsolen-Logs von Signals ab:
  // SignalsObserver.instance = null;

  // 2. (Optional) Wenn du auch das Tracking für die Flutter DevTools deaktivieren willst:
  // signalsDevToolsEnabled = false;

  setupArchitecture();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: WeatherScreen());
  }
}

// --- PRESENTATION LAYER (UI) ---
class WeatherScreen extends StatelessWidget {
  const WeatherScreen({super.key});

  @override
  Widget build(BuildContext context) {
    final controller = di<WeatherController>();

    return Scaffold(
      appBar: AppBar(title: const Text('Wetter App (Signals & GetIt)')),
      body: Center(
        // Hier ist der korrekte SignalBuilder
        child: SignalBuilder(
          builder: (context) {
            if (controller.isLoading.value) {
              return const CircularProgressIndicator();
            }

            return Text(
              controller.weatherData.value ?? 'Noch keine Daten geladen.',
              style: const TextStyle(fontSize: 20),
            );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => controller.loadWeather('Dresden'),
        child: const Icon(Icons.refresh),
      ),
    );
  }
}

Clone this wiki locally