簡體   English   中英

Aurelia-通過注入訪問更新的類屬性?

[英]Aurelia - accessing updated class properties from injection?

我仍在嘗試尋找Aurelia JS的答案-發出同步HTTP請求,以在頁面加載之前更改數據? -因此,我在該示例的代碼示例中嘗試了以下代碼:https://gist.run/?id=90d98563621fe49c1dde6b4f2fc6961d

根據Aurelia-如何更改綁定變量,因此GUI也會更改? ,我知道可以更改作為HTML綁定源的類變量,並且應該更新HTML / GUI。 因此,我正在嘗試上述要點中的類似內容-具體來說,我正在嘗試更改ContactList類的contacts數組屬性(在contact-list.js )。

這是app-clist.js中的相關更改:

import {WebAPI} from './web-api';
import {HttpClient} from 'aurelia-http-client';
import {ContactList} from './contact-list';
import {Container} from 'aurelia-dependency-injection';

// for multiline string, use backticks `` - ES6 template literals.
let phpcode = `
<?php
$outarr = array();

$tObj = new StdClass();
$tObj->{'id'} = '1';
$tObj->{'firstName'} = 'Bob';
$tObj->{'lastName'} = 'Glass';
$tObj->{'email'} = 'bob@glass.com';
$tObj->{'phoneNumber'} = '243-6593';
array_push($outarr, $tObj);
$tObj = new StdClass();
$tObj->{'id'} = '2';
$tObj->{'firstName'} = 'Chad';
$tObj->{'lastName'} = 'Connor';
$tObj->{'email'} = 'chad@connor.com';
$tObj->{'phoneNumber'} = '839-2946';
array_push($outarr, $tObj);

echo json_encode($outarr); 
?>
`;

export class AppClist { // in gist example is wrong, still called App
  static inject() { return [WebAPI, HttpClient, ContactList]; }

  constructor(api, http, conlist){
    this.api = api;
    this.http = http;
    this.conlist = conlist;
    var phpcodesl = phpcode.replace(/(?:\r\n|\r|\n)/g, ' ');
    var encphpcode = encodeURIComponent(phpcodesl); // urlencode
    //alert(encphpcode); 
    // NOTE: gist.run due https will not allow loading from http
    //this.http.post("https://phpfiddle.org/api/run/code/json", "code="+encphpcode )
    //.then(response => {alert(response.response); console.log(response);}) // does not work
    // this does work:
    console.log("a1", this.conlist, this.conlist.contacts);
    this.http.createRequest('https://phpfiddle.org/api/run/code/json')
     .asPost()
     .withHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8')
     .withContent("code="+encphpcode)
     .send()
     .then(response => {
         alert(response.response);
         console.log(response);
         var respobj = JSON.parse(response.response);
         var respdataArr = JSON.parse(respobj.result);
         this.api.setContactList(respdataArr);
         console.log("a2", this.conlist, this.conlist.contacts, this.conlist.getThis(), Container.instance.get(ContactList));
     }).catch(err => {
         console.log(err); 
     })
    ;
  }
...

...並且我在contact-list.js添加了這個console.log語句:

  created(){
    this.api.getContactList().then(contacts => { 
      this.contacts = contacts;
      console.log("b1", this, this.contacts);  });
  }

...以及contact-list.js此功能:

  getThis(){
    return this;
  }

但是,當我運行此命令(單擊“開始單擊我的按鈕”后)時,在Chromium瀏覽器的錯誤日志中得到了此消息:

VM2198 app-clist.js!transpiled:48

a1 ContactList {api: WebAPI, contacts: Array[0]} []
...

contact-list.js:21

b1 ContactList {api: WebAPI, __observers__: Object} [Object, Object, Object, Object, Object]
...

VM2198 app-clist.js!transpiled:55 

a2 ContactList {api: WebAPI, contacts: Array[0]} []
ContactList {api: WebAPI, contacts: Array[0]}
ContactList {api: WebAPI, contacts: Array[0]}
...

因此,這就是我的解釋方式:

  • 消息a1打印在AppClist類的AppClist constructor()中-它首先運行; 那時,通過注入使ContactList類成為AppClist名為conlist的類屬性。 此時,可以理解AppClist.conlist.contacts (即ContactList.contacts )數組為空,大小為0。
  • 消息b1的當打印ContactList是組分created() ,所述后ContactList.contacts陣列已經被初始化,並且被印刷的第二-再次,如預期,有中5個元素contacts陣列
  • HTTP調用完成時,將打印消息a2我本來可以在contacts數組中包含5個元素,但是有0個元素(與訪問方法無關)?

所以,我的問題是-當應該至少有5個contacts數組時,為什么我得到0作為contacts數組的大小? inject是否可以緩存應該引用的變量/類的狀態? 如何獲得對AppClist類中ContactList類的contacts數組屬性的最新狀態的引用?

好吧,我想我找到了解決方法-盡管這只是一些猜測,所以我仍然希望有人提出正確的答案。

首先,我認為問題是“緩存”,但看起來很有可能發生,例如Container.instance.get(ContactList)返回該類的實例,而不是現有實例。 這是我發現的一些相關報價:

增強的依賴項注入使用·問題#73·aurelia / dependency-injection·GitHub建議使用以下方法:

  // configure the container let container = aurelia.container; container.registerInstance(ApiClient, new ApiClient(isDebug)); ... aurelia.start().then(a => a.setRoot()); ... 

...在main.js -我嘗試將其應用於ContactList類,但無法使我的示例正常工作...

如果Aurelia理解“導入”,為什么要使用依賴注入?

這是因為Aurelia的依賴注入容器正在為您實例化一個實例。 ...
您正在告訴Aurelia:“我需要其中之一,請給我。”而Aurelia說:“當然,我已經創建了一個,或者我已經有一個在附近了,這就是。”

嗯,在我的示例中,當我們到達“ a2”日志時,DI應該已經“知道”它已經創建了一個ContactList ,但是顯然無論如何它仍然會創建一個新對象...

如何在Aurelia中創建單例服務?

默認情況下,DI容器假定一切都是單例實例; 該應用的一個實例。 但是,您可以使用注冊修飾符來更改此設置。

好吧,很明顯,在上面的示例中,它並沒有假定ContactList是這樣的!

對我來說,解決方案來自上一篇文章中的另一個答案: 如何在Aurelia中創建單例服務?

所以我意識到我在想這個太難了。 我試圖依靠框架(Aurelia)來完成所有工作,但實際上,這是一個簡單的ES6類更改,使其成為一個實例。

...這是我如何將其應用於ContactList類,並添加cl_instance變量:

import {EventAggregator} from 'aurelia-event-aggregator';
import {WebAPI} from './web-api';
import {ContactUpdated, ContactViewed} from './messages';

let cl_instance = null;

export class ContactList {
  static inject = [WebAPI, EventAggregator];

  constructor(api, ea){
    if(!cl_instance) {
    cl_instance = this;

    this.api = api;
    this.contacts = [];

    ea.subscribe(ContactViewed, msg => this.select(msg.contact));
    ea.subscribe(ContactUpdated, msg => {
      let id = msg.contact.id;
      let found = this.contacts.find(x => x.id === id);
      Object.assign(found, msg.contact);
    });
    } // end if!
    return cl_instance;
  }
  ....

這樣,顯然ContactList類現在的行為就像一個單例(?!),因此,每次我請求引用一個類實例時,我都會得到相同的類實例(而不是實例化一個新的實例)。

這也意味着現在AppClist this.conlist.contacts引用了ContactList的實際數據源contacts屬性變量,因此,現在為其分配將觸發綁定並更新GUI-這樣就解決了Aurelia JS中的問題-制作同步HTTP請求,在頁面加載之前更改數據? -我已將該示例保存在https://gist.run/?id=f4bd01c99f9973cb76d8640f6248c2e3上以供參考

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM