Pomyślałem o eksperymencie wywodzącym się z przypadku, w którym musiałem czasami dodawać i usuwać funkcję dla wyjścia mojego komponentu Angular. To jest przykład

Komponent nadrzędny będzie zawierał tylko funkcję wyjściową dla komponentu podrzędnego <my-component>.

ParentComponent

class ParentComponent{
  myOutputFunction = null;

  setOutputFunction() {
    this.myOutputFunction = () => {
      // do something
    };
  }

  removeOutputFunction() {
    this.myOutputFunction = null;
  }
}

Szablon dla komponentu nadrzędnego

<my-component (someOutput)="myOutputFunction($event)"><my-component>

Komponent potomny MyComponent będzie zawierał wyjście someOutput w środku. Będzie to również służyć jako pytanie, jak wykryć, kiedy rodzic zdecydował się zrobić removeOutputFunction() i potencjalnie zasubskrybować to wydarzenie i zareagować na nie.

Komponent podrzędny MyComponent

class MyComponent {
  @Output() someOutput = new EventEmitter();

  ngOnInit(): void {
    // At this point we can see if there are any observers to someOutput
    if(this.someOutput.observers.length > 0) {
      console.log('YEY we have a set output method from ParentComponent to MyComponent`s attribute');
    } else {
      console.log('We have no attribute defined');
    }
  }
}

W ngOnInit() możemy sprawdzić, czy zakodowaliśmy (someOutput)="myOutputFunction($event)".

A więc konkluzja. Czy istnieje sposób, aby nasłuchiwać (subskrybować) zmiany wartości someOutput z wartości nadrzędnej z wartości () => // do something na wartość null.

Kiedy loguję this.someOutput.observers, otrzymuję tablicę subskrybentów. Czy mogę w jakiś sposób użyć this.someOutput jako EventEmittera, aby dotrzeć do tego eksperymentu?

Dzięki

2
Mario Petrovic 2 kwiecień 2020, 19:23

3 odpowiedzi

Najlepsza odpowiedź

Nie możesz dynamicznie usuwać atrybutu wyjściowego, ale myślę, że to rozwiązanie może ci pomóc.

Jeśli chcesz ustawić wartości od rodzica do dziecka, powinieneś użyć @Input w komponencie podrzędnym.

@Output służy do powiadamiania rodzica o czymś od dziecka.

Rozwiązanie 1

Jeśli chcesz, aby dzieci emitowały wartości tylko wtedy, gdy rodzic ma funkcję, powiedz składnikowi podrzędnemu, gdy ktoś nasłuchuje.

Załóżmy, że emitowane wartości są typu string

Komponent podrzędny

class MyComponent {
  @Output() someOutput: EventEmitter<string> = new EventEmitter();
  @Input() isParentListening = false;

  ngOnInit(): void {
    if (this.isParentListening) {
      // Parent wants to receive data
      this.someOutput.emit("Yay! Parent is listening");
    } else {
      // Parent is not listening
      console.log("My parent doesn't take care of me :(");
    }
  }
}

Komponent nadrzędny

<my-component
  [isParentListening]="listenChildComponent"
  (someOutput)="myOutputFunction($event)"
></my-component>
class ParentComponent {
  listenChildComponent = true;

  myOutputFunction = (value: string) => {
    // do something
  };
}

Rozwiązanie 2

Innym rozwiązaniem jest utrzymywanie komponentu podrzędnego w czystości i nieświadomości tej logiki, a rodzic decyduje, czy musi coś zrobić, czy nie.

Komponent podrzędny

class MyComponent {
  @Output() someOutput: EventEmitter<string> = new EventEmitter();

  ngOnInit(): void {
    // Output always as if someone were listening
    this.someOutput.emit("Yay! Someone is listening (I hope)");
  }
}

Komponent nadrzędny

Rodzic po prostu nie implementuje żadnej logiki, gdy wystąpi to zdarzenie wyjściowe.

<my-component (someOutput)="()=>{}"></my-component>
class ParentComponent {}
1
adrisons 14 kwiecień 2020, 08:36

Dlaczego nie skorzystać z wejścia?

class MyComponent {
  @Input() func = null;

  ngOnInit(): void {
    if (func)
       func();
    else
       console.log("I'm child")
  }
}

W twoim rodzicu

   <app-child [func]="functionInParent"></app-child>

   functionInParent()
   {
         console.log("function in parent") 
   }

   //OR
   <app-child></app-child>
0
Eliseo 14 kwiecień 2020, 10:14

To bardzo ciekawy pomysł. ale żeby mieć pewność, że robisz to we właściwym czasie, powinieneś wysłuchać zdarzenia „newListener” i wykonać tam swoją logikę. sprawdź ten link jako odniesienie https://nodejs.org/api/events.html#events_event_newlistener

....
this.someOutput.once('newListener', (event, listener) => {
    ... // you have a listener
})

...
-2
zzimick 3 kwiecień 2020, 12:19