Polymer data binding — (EP2) Binding to Object

สวัสดีครับ EP2 นี่ ทิ้งห่างกับ EP1 มากๆ สงสัยคุณผู้อ่านคงลืม EP1 ไปแล้ว 555 ซึ่งในบทนี้ผมจะมาอธิบายเรื่อง การผูกกันของข้อมูลที่เป็น Object
เรามาดูตัวอย่าง Code กันเลยดีกว่า
<div>
[[user.name]]
</div>///////////////////////////static get properties() {
return {
user:{
value:{ name:'Namkhaeng', age:18 }
}
};
}
จากโค้ดด้านบนผลลัพธ์จะออกมาแบบนี้ครับ
Namkhaengทีนี้ผมต้องการเปลี่ยนชื่อจาก Namkhaeng เป็น Pongpanot ผมก็แค่สร้างปุ่มไว้อันนึง ให้เรียกฟังก์ชันเปลี่ยนชื่อมา โดยมีโค้ดดังนี้
<div>
[[user.name]]
</div>
<button on-click="changeName">ปุ่ม change</button>///////////////////////////static get properties() {
return {
user:{
value:{ name:'Namkhaeng', age:18 }
}
};
}changeName(){
this.user.name = 'Pongpanot'
}
แต่เมื่อเราลองกดปุ่ม change ปรากฏว่าข้อความคำว่า Namkhaeng ยังไม่เปลี่ยนเป็น คำว่า Pongpanot ครับ **เอาแล้วๆ ทำไมไม่เปลี่ยนวะเนี้ย
จากโค้ดด้านบนเมื่อกดปุ่ม ผลลัพธ์จะออกมาเหมือนเดิม
Namkhaeng(ปุ่ม change)
แต่ถ้าหากเรากำหนดแบบนี้ ในฟังก์ชัน changeName แทนละ
changeName(){
this.user = { name:'Pongpanot', age:18 }
}จากโค้ดด้านบนเมื่อกดปุ่ม change ผลลัพธ์จะออกมาแบบนี้
Pongpanot(ปุ่ม change)
ปรากฏว่าข้อความเปลี่ยนเป็น Pongpanot แล้ว เย้ๆ อ้าวแล้วทำใมต้องกำหนดใหม่ด้วย ไม่มีอย่างอื่นเหรอ ทำใมมันถึงเป็นอย่างงั้นนะ
จากตอนที่แล้วถ้ายังจำได้ เมื่อเรากำหนด Property. Polymer จะทำการสร้าง Property Effects แล้วก็จะสร้าง Setter ของ Property นั้น และเมื่อจะกำหนดโค้ดแบบด้านล่างนี้ Setter ของ Property นั้นจะถูกเรียก ต่อด้วย Property Effects จะถูกเรียกต่อ จึงทำให้ข้อความถูกเปลี่ยนนั่นเอง
this.user = { name:'Pongpanot', age:18 }
//กำหนดแบบนี้ Setter ของ Propety ที่ชื่อว่า name จะถูกเรียกแต่ถ้าเรากำหนดแบบ Sub Property แบบด้านล่างนี้ Setter ก็จะไม่มีเหตุผลที่จะถูกเรียกใช้งาน และ Property Effect ก็จะไม่ทำงาน ทำให้ข้อมูลไม่เปลี่ยนบนหน้าจอนั่นเอง แต่ข้อมูลใน Property ถูกเปลี่ยนไปแล้วนะ แต่ว่าตอนแสดงผลไม่เปลี่ยนเฉยๆ
this.user.name = 'Pongpanot'
//กำหนดแบบนี้ Setter จะไม่ถูกเรียกแล้วถ้าจะทำให้ข้อมูลเปลี่ยนโดยการกำหนด Sub Property ไปเลยเราจะทำอย่างไรละ
ต้องอธิบายก่อนว่าเรากำหนด [[user.name]] แบบนี้ใน Template มันจะถูกเก็บไว้ในบัญชี Property Effects มันจะเปลี่ยนก็ต่อเมื่อมันถูกแจ้งว่าให้เปลี่ยน แต่มันดันไม่ถูกเรียกเพราะว่ามันไม่เข้า Setter เพราะฉนั้นเราก็แจ้งให้เปลี่ยนตรงๆไปเลยโดยการกำหนดแบบนี้
changeName(){
this.user.name = 'Pongpanot'
this.notifyPath('user.name',this.user.name)
}จากโค้ดด้านบนเมื่อกดปุ่ม change ผลลัพธ์จะออกมาแบบนี้
Pongpanot(ปุ่ม change)
สาเหตุที่มันเปลี่ยนเพราะว่า เราก็แค่บอกว่า Path [[user.name]] นี้มีการเปลี่ยนแล้วนะ จากนั้น Polymer มันก็จะไปดูที่ Property Effects ว่าเจ้า [[user.name]] อยู่ที่ไหน จากนั้นก็ไปเปลี่ยนข้อความที่นั่นซะ
โค้ดแบบด้านบนมันยาวไปมีแบบสั้นกว่านี้ไหม?
มีครับ Polymer มีให้คุณใช้หลายทางเลือก กำหนดแบบนี้ไปเลยเป็นไง
changeName(){
this.set('user.name','Pongpanot')
}ทำใม!!! Polymer ถึงทำแบบนี้? ก็นะ..
ลองจินตนาการว่า Property ที่เป็น Object มี Sub Property เป็นพันๆดูซิ…. ช้าแน่นอน คือเราแค่เปลี่ยนไม่กี่จุด เราก็ควรบอกแค่เฉพาะจุดนั้น จะให้มันมาวิ่งดูทั้งหมดก็เสียเวลาเปล่าๆ
จบแล้วคร๊าบบบบบ . ถ้าหากมีอะไรสังสัยก็มาถามได้นะครับ
สำหรับวันนี้ผมง่วงนอนแล้ว…. ฝันดีครับ…
