Обмен данными между Angular компонентами и компонентами, отличными от Angular: возврат данных из наблюдаемого, поступающего из обратного вызова - PullRequest
1 голос
/ 03 августа 2020

У меня есть приложение, которое требует, чтобы я для некоторых вещей использовал не Angular JavaScript. Чтобы вызвать действие в компоненте Angular, я передаю обратный вызов компоненту, отличному от Angular. Когда запускается обратный вызов, наблюдаемый запускается на компоненте Angular (выполняя http-вызов). Это работает, но единственная часть головоломки, с которой у меня возникают проблемы, - это получение данных, возвращаемых из этого наблюдаемого, каким-то образом обратно в компонент, отличный от Angular. Мое настоящее приложение довольно сложное, поэтому я создал Stackblitz для гораздо более упрощенной версии, чтобы было легче увидеть, что я делаю.

Это сложно для меня, поскольку GET вызов в doStuff асинхронный c, поэтому я не могу просто вернуть результаты. У меня были бы идеи, как обойти это в чистом приложении Angular ... но я не уверен, как выполнить sh это при обмене данными между компонентом Angular и не Angular one.

app.component.ts:

 export class AppComponent  {

  constructor(private http: HttpClient){}

  doStuff() {
    let randomNum = this.getRandomInt(2); // Simulate different http responses

    this.http.get<any>(`https://jsonplaceholder.typicode.com/todos/${randomNum}`).subscribe(x => {
      if (x === 1) {
        // Here is where I want to share data with the non-Angular component
        console.log(x.id);
      } else {
        // Here is where I want to share data with the non-Angular component
        console.log(x.id);
      }
    });
  }

  ngOnInit() {
   var x = new NonAngularComponent(this.doStuff.bind(this));
  }

  private getRandomInt(max) {
    return Math.floor(Math.random() * Math.floor(max)) + 1;
  }
}

NonAngularComponent.ts:

export class NonAngularComponent {
  constructor(private onSave: () => void) {
    this.init()
  }

  init() {
    const newElement = document.createElement('button');
    newElement.innerHTML = 'Click';

    newElement.addEventListener('click', () => {
      this.onSave(); // Works, but now I need to do something with the results of doStuff()
    });

    document.getElementById('foo').append(newElement);
  }
}

Любые предложения будут очень признательны.

Ответы [ 2 ]

2 голосов
/ 03 августа 2020

Было бы лучше вернуть Observable из вашего doStuff() метода и использовать оператор tap, если вы хотите иметь какой-то побочный эффект в Angular компоненте:

doStuff() {
  let randomNum = this.getRandomInt(2);

  return this.http.get<any>(`https://jsonplaceholder.typicode.com/todos/${randomNum}`).pipe(tap(x => {
    if (x === 1) {
      // Here is where I want to share data with the non-Angular component
      console.log(x.id);
    } else {
      // Here is where I want to share data with the non-Angular component
      console.log(x.id);
    }
  }));
}

non- angular .component.ts

newElement.addEventListener('click', () => {
  this.onSave().subscribe(res => {
    // do whatever you want
  });
});

Forked Stackblitz

1 голос
/ 03 августа 2020

Я думаю, что самым простым решением было бы просто иметь экземпляр вашего NonAngularComponent внутри AppComponent

this.nonAngularComponent = new NonAngularComponent(this.doStuff.bind(this));

И в обратном вызове просто вызвать метод, который вы хотите из NonAngularComponent, например:

doStuff() {
    let randomNum = this.getRandomInt(2);
    this.http
      .get<any>(`https://jsonplaceholder.typicode.com/todos/${randomNum}`)
      .subscribe(x => {
        if (x === 1) {
          // Here is where I want to share data with the non-Angular component
          // console.log(x.id);
          this.nonAngularComponent.doSomething(x);
        } else {
          // Here is where I want to share data with the non-Angular component
          // console.log(x.id);
          this.nonAngularComponent.doSomething(x);
        }
      });
  }

doSomething метод:

  public doSomething(result) {
    console.log("Non-Angular component received result", result);
  }

И вывод на консоль:

enter image description here

Stackblitz: https://stackblitz.com/edit/angular-tddc7q?file=src%2Fapp%2FNonAngularComponent.ts

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...