[英]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
陣列 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說:“當然,我已經創建了一個,或者我已經有一個在附近了,這就是。”
嗯,在我的示例中,當我們到達“ a2”日志時,DI應該已經“知道”它已經創建了一個ContactList
,但是顯然無論如何它仍然會創建一個新對象...
默認情況下,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.