typescript - การแชร์ข้อมูลระหว่างคอมโพเนนต์โดยใช้ Angular service สำหรับ Ajax Datatables
ฉันเป็นมือใหม่ในสาขา Angular! จนถึงตอนนี้ฉันชอบมัน แต่กำลังเจอกับความยากลำบากในกรณีต่อไปนี้ ฉันต้องการส่งข้อมูลจากคอมโพเนนต์หนึ่งไปยังคอมโพเนนต์อีกตัวหนึ่งเมื่อผู้ใช้คลิกที่เซลล์เฉพาะที่มีแท็ก href ใน Datatables ดังนั้นฉันจึงได้สร้างไฟล์ .ts ดังต่อไปนี้
service.ts
import { Injectable } from '@angular/core';
import { HttpClient,HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { BehaviorSubject } from 'rxjs';
@Injectable()
export class MyService {
private protDataSource = new BehaviorSubject<any>({
currentprotData:null
});
currentprotData= this.protDataSource.asObservable();
constructor(
private http: HttpClient
) {}
sendProtData(currentprotData:any){
console.log(currentprotData)
this.protDataSource.next(currentprotData);
}
get(url){
return this.http.get(url)
.pipe(
map(responce=>responce),
catchError(this.handleError)
)
}
}
sender.ts
import { Component, OnInit, OnDestroy, ViewChild, Renderer } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { DataTableDirective } from 'angular-datatables';
import { HttpClient,HttpErrorResponse } from '@angular/common/http';
import { Subject } from 'rxjs';
import { MyService } from '../qmpkb/qmpkb.service';
declare var jquery: any;
@Component({
selector: 'app-sender-page',
templateUrl: './sender.component.html',
styleUrls: ['./sender.component.css'],
providers:[MyService]
})
export class SenderComponent implements OnInit,OnDestroy {
dtOptions: DataTables.Settings = {};
dtTrigger: Subject<any> = new Subject();
private routeSub:any;
errorStr:Boolean;
@ViewChild(DataTableDirective)
datatableElement: DataTableDirective;
constructor(
private route: ActivatedRoute,
private http: HttpClient,
private renderer: Renderer,
private router: Router,
private _myserve:MyService
) { }
ngOnInit(): void {
//let destPath='fileapi/resultFile/jsonData/resultJson/'+this.queryResPath
let destPath='assets/json/fake.json'
this.dtOptions = {
pagingType: 'full_numbers',
ajax: destPath,
processing: true,
serverSide: false,
columns: [
{
title: 'Prot Seq',
render: function (data: any, type: any, row: any, meta) {
if (row["Prot Seq"].trim().length > 0 ){
var array =(row["Prot Seq"].trim()).split('<br>');
array.forEach(function(element, index) {
array[index] ='<a target="_blank" href="/seqfeatures" routerLinkActive="active" seq-link-id=' + element+'>'+element+'</a>';
});
return array.join("<br>");
} else {
return 'No';
}
}
}
]
};
}
ngAfterViewInit(): void {
this.renderer.listenGlobal('document', 'click', (event) => {
if (event.target.hasAttribute("seq-link-id")) {
this._qmpkb.get(url).subscribe((response: any)=>{
this._myserve.sendProtData(response);
}, error=>{
this.errorStr = error;
})
}
})
}
ngOnDestroy(){
this.routeSub.unsubscribe();
this.dtTrigger.unsubscribe();
}
}
receiver.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { HttpClient,HttpErrorResponse } from '@angular/common/http';
import { MyService } from '../qmpkb/qmpkb.service';
declare var require: any
@Component({
selector: 'app-prot-view',
templateUrl: './prot-view.component.html',
styleUrls: ['./prot-view.component.css'],
providers:[MyService]
})
export class ProtViewComponent implements OnInit,OnDestroy {
message:string
constructor(
private route: ActivatedRoute,
private http: HttpClient,
private router: Router,
private _myserve:MyService,
) { }
ngOnInit() {
this._myserve.currentprotData.subscribe(currentprotData=>{
this.message=currentprotData
})
}
ngAfterViewInit(): void {
console.log(this.message)
}
ngOnDestroy(){
}
}
บริการของฉันสามารถรับข้อมูลได้ แต่ตัวรับข้อมูลมักจะส่งค่ากลับเป็น null ฉันอยากรู้จริงๆ ว่ามีอะไรผิดพลาดตรงไหน! ฉันซาบซึ้งจริงๆ กับความช่วยเหลือและคำแนะนำของคุณ!
อัปเดต ตามที่ DeborahK แนะนำให้รวมส่วนของโครงการใน Stackblitz! คุณสามารถดูว่าฉันกำลังพยายามสร้างโครงการนี้อย่างไร!
สแต็กบลิทซ์
คำตอบ #1
มีปัญหาบางอย่าง วิธีที่ง่ายคือถ้าคุณกำลังสมัครสมาชิกกับ sendProtData().subscribe ใน receiver.ts นั่นไม่ถูกต้อง คุณจำเป็นต้องสมัครสมาชิกกับ BehaviorSubject และ sendProtData() ก็ ไม่มีประเภทการคืนค่า เช่นกัน
ทำให้ protDataSource เป็นสาธารณะและสมัครใช้งานมัน
public protDataSource = new BehaviorSubject<any>({
currentprotData:null
});
และจากนั้นใน receiver.ts:
ngOnInit() {
this._myserve.protDataSource.subscribe(currentprotData=>{
this.message=currentprotData
})
นี่ก็ได้ผลเช่นกัน
อัปเดต :
ตรวจสอบเดโมที่ทำงานนี้
ฉันแก้ไขสิ่งต่อไปนี้เพื่อให้มันใช้งานได้:
คุณไม่ควรฉีดบริการโดยใช้
provider:[]ใน@Componentเพราะมันจะสร้างอินสแตนซ์ใหม่ของบริการสำหรับแต่ละคอมโพเนนต์ ซึ่งคุณไม่ต้องการแบบนั้น คุณต้องการให้ทั้งสองคอมโพเนนต์แชร์อินสแตนซ์ของบริการเดียวกันเพื่อแชร์ข้อมูล ดังนั้นควรฉีดใน@NgModuleในapp.module.tsในโค้ดตัวอย่าง ไม่มี
<app-receiver></app-receiver>ผมได้เพิ่มอันนั้นเข้าไปด้วยเพื่อเริ่มต้นคอมโพเนนต์
ฉันหวังว่ามันจะช่วยได้นะ :) ขอบคุณที่สร้างเดโม
คำตอบ #2
ลองย้าย console.log ของคุณ:
แทนที่จะเป็นสิ่งนี้:
ngOnInit() {
this._myserve.sendProtData.subscribe(currentprotData=>{
this.message=currentprotData
})
}
ngAfterViewInit(): void {
console.log(this.message)
}
ลองอันนี้:
ngOnInit() {
this._myserve.sendProtData.subscribe(currentprotData=>{
this.message=currentprotData;
console.log(this.message);
})
}
