Angular 通过 Angular 服务在 Angular 组件之间路由主题的 4/5 问题
Angular 4/5 issue with routing Subject between Angular components via Angular Services
我有一个带有 HTML 单击事件的父组件,它将单击的元素传递给 component.ts 文件上的方法,我希望将此单击事件路由到服务,制作成一个新的 Subject
,然后使用 next()
方法,将 Subject 传递给不同的 Sibling Component,并将数据绑定到 Sibling Component 的 HTML.
因此此数据的路由将如下所示:
父组件(通过点击事件) --> 服务(通过父组件的方法)--> 兄弟组件(通过服务)*
这是我的数据传递开始的地方:
app.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { ApiService } from '../api.service';
@Component({
selector: 'app-contacts-list',
templateUrl: './contacts-list.component.html',
styleUrls: ['./contacts-list.component.scss']
})
export class ContactsListComponent implements OnInit {
sortedFavorites: any[] = [];
sortedContacts: any[] = [];
constructor (private _apiService: ApiService, private router: Router) {}
ngOnInit(){ this.getContacts()}
getContacts() {
this._apiService.getContacts()
.subscribe(
(contacts) => {
//Sort JSON Object Alphabetically
contacts.sort( (a, b) => {
if (a.name > b.name) return 1;
if (a.name < b.name) return -1;
return 0;
});
//Build new Sorted Arrays
contacts.forEach( (item) => {
if (item.isFavorite) {
this.sortedFavorites.push(item);
} else {
this.sortedContacts.push(item);
}
});
});
}
openFavorite($event, i) {<--HTML click event passing 'i' in as object clicked
let selectedFavorite = this.sortedFavorites[i];
this._apiService.openSelectedContact(selectedFavorite); <--passing said object into method connected to my services.ts file
this.router.navigate(['/details']);
};
}
我使用我创建的 openFavorite()
方法传递的数据正在运行,因为执行 console.log(selectedFavorite)
记录了要传递的所需结果。
然后就交给服务了
app.service.ts:
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/map';
@Injectable()
export class ApiService {
//API URL
private url: string = 'assets/api/contacts.json';
//Create new Subject and assign to local variable
public newContactSubject = new Subject<any>();
//Initialize HttpClient for request
constructor(private _http: Http) { }
//Pull JSON data from REST API
getContacts(): Observable<any> {
return this._http.get(this.url)
.map((response: Response) => response.json());
}
openSelectedContact(data) {
this.newContactSubject.next(data); <---Where data should be passing in!
}
}
**现在我希望我的其他组件接收来自 app.service 的数据。
import { Component, OnInit } from '@angular/core';
import { ContactsListComponent } from './app/contacts-list/contacts-list.component';
import { ApiService } from '../api.service';
@Component({
selector: 'app-contact-details',
templateUrl: './contact-details.component.html',
styleUrls: ['./contact-details.component.scss']
})
export class ContactDetailsComponent implements OnInit {
selectedContact: any[] = [];
error: string;
constructor(private _apiService: ApiService) { }
ngOnInit() { this.showContact() }
showContact() {
this._apiService.newContactSubject.subscribe(
data => this.selectedContact = data) <--Where the data should be showing up from services.ts file
console.log(this.selectedContact.name); <-- This is logging Undefined
}
}
我会在这里遗漏什么?提前致谢!
试试这个:
showContact() {
this._apiService.newContactSubject.subscribe(
data => {
this.selectedContact = data;
console.log(this.selectedContact.name);
}
}
两行代码(包括您的日志记录)都在传递给订阅的函数中。每次发出一个项目时,它只运行 回调函数中的代码。
附带说明...通常建议您将主题设为私有,并且仅公开它 read-only 可观察的,使用如下代码:
private selectedMovieSource = new Subject<IMovie | null>();
selectedMovieChanges$ = this.selectedMovieSource.asObservable();
请注意,主题是私有的,它的可观察性是使用单独的 属性 公开的。然后组件订阅主题的 public observable。
首先,您的组件的排序方法永远不会排序,因为您忽略了 return 值。如果你想处理排序,你应该像这样使用 concatcts = contacts.sort(...)
我建议您使用另一种模式:
import { Component, OnInit } from '@angular/core';
import { ContactsListComponent } from './app/contacts-list/contacts-list.component';
import { ApiService } from '../api.service';
import { OnDestroy } from "@angular/core";
import { ISubscription } from "rxjs/Subscription";
@Component({
selector: 'app-contact-details',
templateUrl: './contact-details.component.html',
styleUrls: ['./contact-details.component.scss']
})
export class ContactDetailsComponent implements OnInit, OnDestroy {
selectedContact: any[] = [];
error: string;
private subscription: ISubscription;
constructor(private _apiService: ApiService) { }
ngOnInit() {
this.subscription = this._apiService.newContactSubject().subscribe(data => {
this.selectedContact = data;
console.log(this.selectedContact.name);
});
}
showContact() {
this._apiService.newContactSubject.subscribe();
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
但我发现还有另一个问题:您已将 selectedContact
定义为 any 对象数组,然后您希望将值作为对象获取:this.selectedContact.name
希望你能解决这个问题:)
我有一个带有 HTML 单击事件的父组件,它将单击的元素传递给 component.ts 文件上的方法,我希望将此单击事件路由到服务,制作成一个新的 Subject
,然后使用 next()
方法,将 Subject 传递给不同的 Sibling Component,并将数据绑定到 Sibling Component 的 HTML.
因此此数据的路由将如下所示:
父组件(通过点击事件) --> 服务(通过父组件的方法)--> 兄弟组件(通过服务)*
这是我的数据传递开始的地方:
app.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { ApiService } from '../api.service';
@Component({
selector: 'app-contacts-list',
templateUrl: './contacts-list.component.html',
styleUrls: ['./contacts-list.component.scss']
})
export class ContactsListComponent implements OnInit {
sortedFavorites: any[] = [];
sortedContacts: any[] = [];
constructor (private _apiService: ApiService, private router: Router) {}
ngOnInit(){ this.getContacts()}
getContacts() {
this._apiService.getContacts()
.subscribe(
(contacts) => {
//Sort JSON Object Alphabetically
contacts.sort( (a, b) => {
if (a.name > b.name) return 1;
if (a.name < b.name) return -1;
return 0;
});
//Build new Sorted Arrays
contacts.forEach( (item) => {
if (item.isFavorite) {
this.sortedFavorites.push(item);
} else {
this.sortedContacts.push(item);
}
});
});
}
openFavorite($event, i) {<--HTML click event passing 'i' in as object clicked
let selectedFavorite = this.sortedFavorites[i];
this._apiService.openSelectedContact(selectedFavorite); <--passing said object into method connected to my services.ts file
this.router.navigate(['/details']);
};
}
我使用我创建的 openFavorite()
方法传递的数据正在运行,因为执行 console.log(selectedFavorite)
记录了要传递的所需结果。
然后就交给服务了
app.service.ts:
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/map';
@Injectable()
export class ApiService {
//API URL
private url: string = 'assets/api/contacts.json';
//Create new Subject and assign to local variable
public newContactSubject = new Subject<any>();
//Initialize HttpClient for request
constructor(private _http: Http) { }
//Pull JSON data from REST API
getContacts(): Observable<any> {
return this._http.get(this.url)
.map((response: Response) => response.json());
}
openSelectedContact(data) {
this.newContactSubject.next(data); <---Where data should be passing in!
}
}
**现在我希望我的其他组件接收来自 app.service 的数据。
import { Component, OnInit } from '@angular/core';
import { ContactsListComponent } from './app/contacts-list/contacts-list.component';
import { ApiService } from '../api.service';
@Component({
selector: 'app-contact-details',
templateUrl: './contact-details.component.html',
styleUrls: ['./contact-details.component.scss']
})
export class ContactDetailsComponent implements OnInit {
selectedContact: any[] = [];
error: string;
constructor(private _apiService: ApiService) { }
ngOnInit() { this.showContact() }
showContact() {
this._apiService.newContactSubject.subscribe(
data => this.selectedContact = data) <--Where the data should be showing up from services.ts file
console.log(this.selectedContact.name); <-- This is logging Undefined
}
}
我会在这里遗漏什么?提前致谢!
试试这个:
showContact() {
this._apiService.newContactSubject.subscribe(
data => {
this.selectedContact = data;
console.log(this.selectedContact.name);
}
}
两行代码(包括您的日志记录)都在传递给订阅的函数中。每次发出一个项目时,它只运行 回调函数中的代码。
附带说明...通常建议您将主题设为私有,并且仅公开它 read-only 可观察的,使用如下代码:
private selectedMovieSource = new Subject<IMovie | null>();
selectedMovieChanges$ = this.selectedMovieSource.asObservable();
请注意,主题是私有的,它的可观察性是使用单独的 属性 公开的。然后组件订阅主题的 public observable。
首先,您的组件的排序方法永远不会排序,因为您忽略了 return 值。如果你想处理排序,你应该像这样使用 concatcts = contacts.sort(...)
我建议您使用另一种模式:
import { Component, OnInit } from '@angular/core';
import { ContactsListComponent } from './app/contacts-list/contacts-list.component';
import { ApiService } from '../api.service';
import { OnDestroy } from "@angular/core";
import { ISubscription } from "rxjs/Subscription";
@Component({
selector: 'app-contact-details',
templateUrl: './contact-details.component.html',
styleUrls: ['./contact-details.component.scss']
})
export class ContactDetailsComponent implements OnInit, OnDestroy {
selectedContact: any[] = [];
error: string;
private subscription: ISubscription;
constructor(private _apiService: ApiService) { }
ngOnInit() {
this.subscription = this._apiService.newContactSubject().subscribe(data => {
this.selectedContact = data;
console.log(this.selectedContact.name);
});
}
showContact() {
this._apiService.newContactSubject.subscribe();
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
但我发现还有另一个问题:您已将 selectedContact
定义为 any 对象数组,然后您希望将值作为对象获取:this.selectedContact.name
希望你能解决这个问题:)