AngularDart: How do you pass an event from a Child component to a second level parent

前端 未结 2 1352
春和景丽
春和景丽 2021-01-24 01:50

I am using StreamControllers with Events, and essentially I have a 3 level component heirarchy lets call them, A,B,C. The heirarchy is A -> B -> C.

The origin of the eve

相关标签:
2条回答
  • 2021-01-24 02:19

    I think it is easier just to create an "event bus" singleton service that is injected in Component A and Component C.

    Here is the code:

    class Event {
         // your data
    }
    
    @Injectable()
    class EventBus {
    
        final StreamController<Event> _onEventStream = new StreamController<Event>();
        Stream<Selection> onEventStream = null;
    
        static final EventBus _singleton = new EventBus._internal(); 
    
        factory EventBus() {
             return _singleton;
        }
    
        EventBus._internal() {
             onEventStream = _onEventStream.stream;
        }
    
        onEvent(Event event) {
             _onEventStream.add(selection);
        }
    }
    
    
    @Component(
       selector: 'C',
       templateUrl: 'C.html',
       providers: const [
           EventBus
       ]
     )
     class C {
    
         final EventBus _eventBus;
    
         C(this._eventBus);
    
         onAction() {
             _eventBus.onEvent(new Event());
        }
     }
    
    
    @Component(
        selector: 'A',
        templateUrl: 'A.html',
        providers: const [
            EventBus
        ]
    )
    class A {
    
        final EventBus _eventBus;
    
        A(this._eventBus) {
            _eventBus.onEventStream.listen((Event e) => /* do something with the event */)
        }
    }
    
    0 讨论(0)
  • 2021-01-24 02:36

    Thanks for asking.

    There are a couple ways to do this.

    (1) Create an event handler in B that forwards from C

    @Component(
      selector: 'b',
      directives: const [C],
      template: '<c (event)="cDidEvent()"></c>',
    )
    class B {
      final _onEvent = new StreamController();
      Stream get onEvent => _onEvent.stream;
    
      void cDidEvent() {
        _onEvent.add(null);
      }
    }
    

    (2) Use dependency injection.

    This requires deeper coupling between components, so it won't be appropriate for all designs, but it could make sense in some scenarios.

    abstract class OnEvent {
      /// Called when an event happens.
      void onEvent();
    }
    
    @Component(
      selector: 'a',
      directives: const [B],
      template: '<b></b>',
      providers: const [
        const Provider(OnEvent, useExisting: A),
      ],
    )
    class A implements OnEvent {
      @override
      void onEvent() {
        print('>>> An event was triggered!');
      }
    }
    
    class C {
      final OnEvent _eventHandler;
    
      C(this._eventHandler);
    
      void onSomeAction() {
        _eventHandler.onEvent();
      }
    }
    
    0 讨论(0)
提交回复
热议问题