โพลีเมอร์ โปรดสังเกตเส้นทางโลกด้วย

ใน Polymer 1.0 คุณสามารถปล่อย {{localPropFoo.bar}} และ bar จะถูกสังเกตการเปลี่ยนแปลงหากคุณใช้ this.set('localPropFoo.bar', 'new value'); เพื่ออัปเดตค่าของมัน

แต่จะทำอย่างไรถ้าคุณต้องการผูกเทมเพลตกับวัตถุภายนอกที่อยู่นอกเหนือการควบคุมของคุณ? เช่น {{window.globalFoo.bar}} นี้จะไม่เชื่อมโยงกับการเปลี่ยนแปลง bar เนื่องจากโค้ดภายนอกไม่ได้ขึ้นอยู่กับ Polymer และไม่ได้เรียก this.set

สาธิตเกี่ยวกับ codepen

การใช้ Object.observe ด้วยตนเองต้องใช้โค้ดเพิ่มเติมและใช้งานไม่ได้ใน FireFox (การตรวจสอบสกปรกของ observe.js เพื่อ การช่วยเหลือ).

ฉันต้องการทราบว่าวิธีสำนวนการเชื่อมโยงข้อมูลกับวัตถุภายนอกที่อยู่นอกเหนือการควบคุมของคุณคืออะไร


person ilyaigpetrov    schedule 12.09.2015    source แหล่งที่มา
comment
คุณได้ลองใช้สัญญาณเหล็กแล้วหรือยัง? สามารถฟังเหตุการณ์ iron-signal-* โดยไม่คำนึงถึงตำแหน่งใน DOM   -  person Neil John Ramal    schedule 12.09.2015
comment
วิธีที่ใช้สำนวนไม่ใช่การผูกมัดกับวัตถุภายนอกที่อยู่นอกเหนือการควบคุมของคุณ คุณใช้ไลบรารีอื่นที่ตั้งค่าไว้หรือไม่ หากคุณควบคุมแอปทั้งหมดของคุณ ก็ไม่จำเป็นต้องควบคุมมัน   -  person Andrey    schedule 12.09.2015
comment
Observe-js เป็นผู้ช่วยคนเดียวของคุณที่นี่ แต่มันเป็นวิธีที่งุ่มง่าม   -  person Andrey    schedule 12.09.2015
comment
@Andrey ฉันใช้ห้องสมุดของตัวเองซึ่งฉันไม่ต้องการพึ่งพาโพลีเมอร์ แต่ฉันสามารถทำให้มันปล่อยเหตุการณ์ได้ไม่ทางใดก็ทางหนึ่งอาจเป็นด้วย Node's EventEmitter   -  person ilyaigpetrov    schedule 12.09.2015
comment
@ilyaigpetrov คุณสามารถใช้กิจกรรม JS ดั้งเดิมได้   -  person Andrey    schedule 12.09.2015
comment
คุณสามารถส่งผ่านการเปลี่ยนแปลงได้ตลอดเวลาโดยเหตุการณ์ที่กำหนดเอง ซึ่งก็คือวิธีนี้ พอลิเมอร์บรรลุผลการสังเกต   -  person wener    schedule 13.09.2015


คำตอบ (1)


Polymer ไม่ได้สังเกตนอกกรอบ เนื่องจาก:

  1. Object.observe การสนับสนุนไม่แพร่หลายและการตรวจสอบสกปรกมีราคาแพง
  2. Object.observeอาจจะมีราคาแพงในตัวเอง

วิธีแก้ปัญหาที่ควรจะเป็น

จับการเปลี่ยนแปลงด้วยตัวคุณเอง โทร notifyPath, this.fire('global-foo-changed', {path: 'globalFoo.bar', value:...}, this.set และ this.push
ทั้งหมดนี้จะจัดส่งเหตุการณ์ที่กำหนดเองที่ไม่เดือดพล่าน (จับภาพ) globalFoo-changed ที่สอดคล้องกัน (เมื่อจำเป็นเท่านั้น)

เหตุใดเหตุการณ์ global-foo-changed ของฉันจึงส่งผลต่อองค์ประกอบ this เท่านั้น

  1. global-foo-changed กำลังจับภาพเหตุการณ์ (ไม่เดือดพล่าน)
  2. องค์ประกอบโพลีเมอร์จะคอยฟังเหตุการณ์ฟองสบู่ตามค่าเริ่มต้น
  3. ด้วยเหตุผลบางประการ ผู้ฟังที่จับภาพเหล่านี้จึงบันทึกเหตุการณ์ฟองสบู่ที่ส่งมาจากองค์ประกอบเดียวกัน (ไม่ใช่จากลูก ๆ ของมัน) สาธิตบน codepen

คุณอาจแก้ไขโพลีเมอร์ด้วยพฤติกรรมนี้ (ฉันไม่เข้าใจว่ามันทำงานอย่างไร):

SharedGlobalsBehavior = {
  properties: {
    globalFoo: {
      type: Object,
      notify: true,
      value: globalFoo
    }
  },
  created: function() {
    window.addEventListener('global-foo-changed', () => {
      if (!event.detail || !event.detail.path)
        return; // Property initialization.
      this.notifyPath(event.detail.path, event.detail.value);
    },/* if capturing */ true);
  }
};

เหตุใดจึงไม่มีการสังเกตนอกกรอบ

...บางครั้งรหัสที่จำเป็นจำเป็นต้องเปลี่ยนคุณสมบัติย่อยของวัตถุโดยตรง เนื่องจากเราหลีกเลี่ยงกลไกการสังเกตที่ซับซ้อนมากขึ้น เช่น Object.observe หรือการตรวจสอบสกปรกเพื่อให้ได้ประสิทธิภาพการเริ่มต้นและรันไทม์ข้ามแพลตฟอร์มที่ดีที่สุดสำหรับกรณีการใช้งานที่พบบ่อยที่สุด การเปลี่ยนแปลงคุณสมบัติย่อยของออบเจ็กต์จึงต้องอาศัยความร่วมมือจากผู้ใช้โดยตรง

โดยเฉพาะอย่างยิ่ง Polymer จัดเตรียมสองวิธีที่อนุญาตให้แจ้งการเปลี่ยนแปลงดังกล่าวไปยังระบบ: notifyPath(path, value) และ set(path, value) โดยที่ path คือสตริงที่ระบุพาธ (สัมพันธ์กับองค์ประกอบโฮสต์)

person ilyaigpetrov    schedule 18.09.2015