Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 数据未从角度上的组件传递_Javascript_Html_Angular - Fatal编程技术网

Javascript 数据未从角度上的组件传递

Javascript 数据未从角度上的组件传递,javascript,html,angular,Javascript,Html,Angular,我试图使用@Input方法在组件之间传递数据。由于某些原因,我在控制台中没有任何错误,但是我试图将数据从内容传递到标题的组件中没有显示任何内容,而标题是标题组件。我有一个主视图组件,它由以下3个组件构成: 主视图 标题 内容 页脚 数据需要从内容组件传递到标题组件。到目前为止,我正在使用@Input方法,但它不起作用 标题.component.ts import { Component, OnInit, Input } from '@angular/core'; import { faHea

我试图使用
@Input
方法在组件之间传递数据。由于某些原因,我在控制台中没有任何错误,但是我试图将数据从内容传递到标题的组件中没有显示任何内容,而标题是标题组件。我有一个主视图组件,它由以下3个组件构成:

主视图

  • 标题
  • 内容
  • 页脚
数据需要从内容组件传递到标题组件。到目前为止,我正在使用@Input方法,但它不起作用

标题.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { faHeadphones} from '@fortawesome/free-solid-svg-icons';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {

  faHeadphones = faHeadphones;

  @Input()playlist= [];

  constructor() { }

  ngOnInit() {
  }
}
import { Component, OnInit } from '@angular/core';
import { ApiService } from '../../../services/api.service';
import { FormGroup, FormControl } from '@angular/forms';
import { FormBuilder } from '@angular/forms';
import { faSearch } from '@fortawesome/free-solid-svg-icons';
import { faRedo } from '@fortawesome/free-solid-svg-icons';
import { faHeadphones } from '@fortawesome/free-solid-svg-icons';
import { faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons';
import { faPlus } from '@fortawesome/free-solid-svg-icons';

@Component({
  selector: 'app-content',
  templateUrl: './content.component.html',
  styleUrls: ['./content.component.scss']
})
export class ContentComponent {

  public data = [];
  public playlist = [];
  public apiData: any;
  public results = [];
  public loading = false;
  public noData: any;
  p: number = 1;
  faSearch = faSearch;
  faRedo = faRedo;
  faHeadphones = faHeadphones;
  faExternalLinkAlt = faExternalLinkAlt;
  faPlus = faPlus;

  searchQuery: string = "";
  clickMessage = '';

  constructor(private service: ApiService) { }

  getAll() {
    this.service.getAll(this.searchQuery).subscribe((results) => {
      this.loading = true;
      console.log('Data is received - Result - ', results);
      this.data = results.results;
      this.loading = false;

      if (this.data.length <= 0) {
        this.noData = true;
      } else if (this.data.length >= 1) {
        this.noData = false;
      } else {
        this.noData = false;
      }
    })
  }

  closeAlert() {
    this.noData = false;
  }

  addSongToPlaylist(itunes) {
    this.playlist.push(itunes);
    console.log('Playlist - ', this.playlist);
}

  refresh(): void {
    window.location.reload();
  }

  Search() {
    this.service.getAll(this.searchQuery).subscribe((results) => {
      this.loading = true;
      console.log('Data is received - Result - ', results);
      this.data = results.results;
      this.loading = false;
    })
  }
  ngOnInit() {

  }
}
import { Component, OnInit } from '@angular/core';
import { ApiService } from '../../services/api.service';

@Component({
  selector: 'app-home-view',
  templateUrl: './home-view.component.html',
  styleUrls: ['./home-view.component.scss']
})
export class HomeViewComponent implements OnInit {

  public playlist = [];

  constructor(private service: ApiService) { }

  ngOnInit() {
  }

}
header.html

<nav class="navbar navbar-dark bg-dark">
  <div class="container">
    <a class="navbar-brand" href="#">
      <fa-icon [icon]="faHeadphones"></fa-icon>
      Navbar
    </a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav"
      aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarNav">
      <ul class="navbar-nav">
        <li class="nav-item active">
          <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Search</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">About</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="#">{{playlist.length}}</a>
          </li>
      </ul>
    </div>
  </div>
</nav>
<app-header [playlist]="playlist"></app-header>
    <app-content ></app-content>
<app-footer></app-footer>

如果我理解清楚的话,这三个组件共享同一个数组(称为播放列表)。问题是播放列表在ContentComponent中被修改

  • 您没有通知家长(HomeViewComponent)该更改
  • 内容和标题组件是同级的,因此,它们无法与简单绑定通信
  • 您有两个选择:

  • 将播放列表逻辑移动到父组件,并通过ContentComponent或
  • 对ContentComponent内的播放列表使用双向绑定
  • 如果选择第二个选项,则可以声明@Output属性,如
    @Output()playlchange=new EventEmitter()
    ,并在每次修改ContentComponent内的数组时调用
    this.playlchange.emit(this.playlist)
    ,也可以在模板中使用
    更改

    不要忘记声明输入属性,如
    @input()playlist:any[]


    注意:为了使用双向绑定,输出属性必须按照我指定的名称命名,我的意思是,如果您的属性命名为x,则输出属性必须命名为xChange

    应用程序内容
    组件中,添加事件发射器

    ...
    @Output() playlistChange: EventEmitter = new EventEmitter<any>();
    ...
    
    现在,在home-view.html中将
    app content
    标记更改为代码下方

    ...
    <app-content (playlistChange)="assignVal($event)"></app-content>
    ...
    

    我找到的最简单的方法是创建一个服务并传递到组件的
    构造函数中:

    import { Injectable } from '@angular/core';
    import { BehaviorSubject } from 'rxjs';
    
    @Injectable({
      providedIn: 'root'
    })
    export class PlaylistService {
    
      public playlist = [];
    
      constructor() { 
    
      }
    }
    

    只能使用@Input()从父组件到子组件共享数据,并且您的内容和标题组件是同级而不是父子组件。您可以使用服务将播放列表从内容传递到标题,或通过@Output将播放列表传递到主页。此外,更新播放列表的方法addSongToPlaylist()从未被调用。您能详细说明一下吗?@Sole,将您的home-view.html修改为-。或者,如果您在home-view.component中的方法内执行此赋值操作,效果会更好。并在组件中添加assignVal(value){this.playlist=value},方法是添加
    @Output()playlchange:EventEmitter=neweventemitter()这给出了
    泛型类型“EventEmitter”需要1个类型参数的错误。
    只需执行@Output()playChange=new EventEmitter();
        assignVal(value){
        this.playlist = value;
    }
    
    import { Injectable } from '@angular/core';
    import { BehaviorSubject } from 'rxjs';
    
    @Injectable({
      providedIn: 'root'
    })
    export class PlaylistService {
    
      public playlist = [];
    
      constructor() { 
    
      }
    }