在新标签中的组件之间传递数据

时间:2019-08-15 01:50:39

标签: javascript angular routes

我在一个组件中有一个对象,我想将其传递给另一组件。问题在于该其他组件将在新标签页中打开。

我尝试使用数据服务策略,但是当选项卡打开时,数据服务对象未定义。

我考虑过使用查询参数并传递url。但是对象很复杂

我的数据服务:

  @Injectable({providedIn: 'root'})
  export class DataService {

   private anime: Anime;

   constructor() { }

   setAnime(anime: Anime) {
    this.anime = anime;
   }
   getAnime() {
    return this.anime;
   }
 }

在数据服务中设置对象

goToDetailsByService(anime: Anime) {
   this.dataService.setAnime(anime);
   //this.router.navigateByUrl('/details');
   window.open('/details');
}

通过服务数据获取动漫对象:

ngOnInit(): void {
  console.log(this.dataService.getAnime());
  this.anime = this.dataService.getAnime()

}

通过导航路由器访问详细信息组件时有效

3 个答案:

答案 0 :(得分:2)

我认为最简单的方法是使用浏览器localStorage,因为那样会保持标签之间的应用状态。当您打开新标签页时,两个网页是分开的,状态不会延续。

因此,您可以使用localStorage

SET

goToDetailsByService(anime: Anime) {
  localStorage.setItem('anime', JSON.stringify(anime));
  window.open('/details');
}

获取

ngOnInit(): void {
  this.anime = JSON.parse(localStorage.getItem('anime'));

  // here you can choose to keep it in the localStorage or remove it as shown below
  localStorage.removeItem('anime');
}

答案 1 :(得分:1)

我认为有两种方法可以做到这一点。第一个是 localStorage ,第二个是 PostMessage

localStorage

我们可以使用localstorage,因为可以在多个窗口之间读取存储,并且在向存储中写入内容时会触发存储事件。

这是代码示例。

// parent window
localStorage.setItem("EVENT.PUB", JSON.stringify(anime));

// child widnow
window.addEventListener('storage', function(event) {
  console.log(event);
  const anime = JSON.parse(event.newValue);
}, false);

postMessage

window.postMessage()方法可以安全地启用Window对象之间的通信;例如,在页面与其产生的弹出窗口之间,或在页面与嵌入其中的iframe之间。

这是代码示例。

// parent window
const detailPage = window.open('/details');
detailPage.postMessage(anime, '*');
// important notice: anime should be object that can be serialize
// otherwise error will happen when execute this function.


// child window
window.addEventListener('message', (event) => {
  // get out the message
  console.log(event.data);
  // and you can even send message back to parent window too.
  event.source.postMessage('Got it!',  event.origin);
}, false);

答案 2 :(得分:-2)

您需要使用BehaviorSubject保留最后一个值。

示例:

@Injectable({providedIn: 'root'})
  export class DataService {

   private anime$ = new BehaviorSubject<Anime>();

   constructor() { }

   setAnime(anime: Anime) {
    this.anime$.next(anime);
   }
   getAnime() {
    return this.anime$;
   }
 }

现在有一些方法可以获取动漫价值。具有可观察性的值(每次值更改时都会触发)。

this.dataService.getAnime().subscribe(anime => {this.anime = anime});

或者直接获取值:

this.anime = this.dataService.getAnime().value;