iT邦幫忙

0

angular service 之間互相存取 property 存在某種限制嗎

問題解決了又解決,又有新問題...

結果不是rxjs的問題,而是如果 angent.component 的 constructor 沒有寫成這樣,或者沒在任何一個component的constuctor寫下這樣的宣告就會發生標題的問題

angent.component

import {agantCtr} from 'src/myservice/agentCtr.service'
import {socketService} from 'src/myservice/socket.service'
constructor(private agantCtr: agantCtr,
              private socketService: socketService
    ) { }

若這邊把private socketService: socketService 拿掉,則socketService
就無法取用angent.componentagentCtr.service 中所更動的值了。

這是angular的時麼保護機制嗎?有點玄妙,官網上說明明說service是singleton啊...

問題(已經解決)

websocket.service 中的某個subscribe, 呼叫了agentCtr.service中的某個function時,agentCtr.servicethis 無法訪問 部分的 property。

首先這個問題有以下role:

  1. websocket.service // 提供前端網頁reactive update的服務(後端API觸發後 會send message到前端來解析要觸發哪些update)

  2. agentCtr.service // 負責 angent.component的資料更新

  3. angent.component // component "Oninit時,會初始化agentCtr.service

前情提要

agentCtr.service中有一個subject,而angent.component利用此subject來設定此agentCtr.service的一些參數,例如 server的ip/port 或 userId之類的 URL參數,當

websocket.service


@Injectable({
  providedIn: 'root'
})
export class socketService {
  // SubjectList
  

  /**
   * Websocket
   * 當socket接收到訊息時,解析並調用指定函數
   * 
   */
  websocket = webSocket<any>(environment.socket);


  constructor(public agentCtr: agantCtr){
    console.log('socket service init')
    // socket subscribe
    this.websocket.subscribe(
      onMsg => {
        let res = onMsg as socketReponse
        console.log({incommingSocketRes: res})
        if(res.action === 'message') {
          console.log({socketMessage: res.body})
        }
        else if (res.action === 'update') {
          // 這個地方 userId 是正確的,curWs是空字串。
          console.log({peekAgentCurWs: this.agentCtr.curWs})
          console.log({peekAgentCuruserid: this.agentCtr.userId})
          
          let body = res.body as forceUpdate
          if(body.target === 'batchComponent') {
            // 這邊呼叫時,getBatchConf中this.userId可以讀取得到
            // getBatchConf中this.curWs是空白的值,但應該要有才對
            this.agentCtr.getBatchConf()
          }
        }
      },
      err => {

      },
      () => {
        console.log()
      }
    )
  }
}

agentCtr.service

@Injectable({
  providedIn: 'root'
})
export class agantCtr {
  userId: string = '';
  curWs: string = '';

  // angent.component 會利用此 Subject 來觸發更新
  currentWs = new Subject<string>();
  
  constructor(private cookieService: CookieService){
      // set
      userId = this.cookieService.get(cookieList.userID);
      
      
      // 當angent.component OnInit時會pass值到currentWs這個Subject
      this.currentWs.subscribe( wsname => {
  
          console.log('switch workspace:'+  wsname)
          // 當 workspace 切換時,載入相依資訊與相依設定
      
          this.curWs = wsname
          this.getBatchConf();
      })
   } // end constructor()
   
   getBatchConf = ()  => {
   
   // 當我從socket.service呼叫時,this.curWs遺失了
   
    console.log('in get batchconfig of :' + this.curWs)
    console.log('user: ' + this.userId)
    let url = `http://${environment.apiserver}/users/${this.userId}/management/api/getBatchConfig/${this.curWs}`;

    this.http.get(url, {
      headers: {
      },
      withCredentials:true
      }).subscribe(data => {
      // do sth
     })
   }
    
   switchWs(WsName: string) {
     this.currentWs.next(WsName)
   }
    
}

angent.component


  @Component({
  selector: 'app-agent',
  templateUrl: './agent.component.html',
  styleUrls: ['./agent.component.css']
})
export class AgentComponent implements OnInit, OnDestroy {
 

  constructor(private http: HttpClient, 
              private route: ActivatedRoute,
              private router: Router,
              private cookieService: CookieService,
              public agentCtr: agantCtr, // angentCtr.service
              private socketService: socketService) { }
              

  ngOnInit(): void {
    console.log('agent component init Start!')
    this.userId = this.cookieService.get(cookieList.userID);
    this.wsName = this.route.snapshot.parent.paramMap.get('wsName');
    // 改變agent所代理的Ws(使set, get Api 針對目前正瀏覽的Ws做操作)
    this.agentCtr.switchWs(this.wsName);
    

尚未有邦友回答

立即登入回答