คุณสามารถโทร ko.applyBindings เพื่อผูกมุมมองบางส่วนได้หรือไม่?


257

ฉันใช้ KnockoutJS และมีมุมมองหลักและมุมมองโมเดล ฉันต้องการไดอะล็อก (หนึ่งใน jQuery UI) เพื่อป็อปอัพพร้อมกับมุมมองอื่นซึ่งจะแยกโมเดลมุมมองชายด์ที่แยกต่างหาก

HTML สำหรับเนื้อหาไดอะล็อกถูกเรียกคืนโดยใช้ AJAX ดังนั้นฉันต้องการที่จะสามารถเรียกใช้งานได้ko.applyBindingsเมื่อคำขอเสร็จสมบูรณ์และฉันต้องการผูกโมเดลมุมมองลูกไว้กับส่วนของ HTML ที่โหลดผ่าน ajax ภายใน div ไดอะล็อก

เป็นไปได้จริงหรือฉันต้องโหลดมุมมองและมุมมองแบบจำลองทั้งหมดของฉันเมื่อหน้าเว็บเริ่มโหลดและโทรko.applyBindingsครั้งเดียว

คำตอบ:


430

ko.applyBindings ยอมรับพารามิเตอร์ตัวที่สองซึ่งเป็นองค์ประกอบ DOM เพื่อใช้เป็นรูท

นี่จะช่วยให้คุณทำสิ่งที่ชอบ:

<div id="one">
  <input data-bind="value: name" />
</div>

<div id="two">
  <input data-bind="value: name" />
</div>

<script type="text/javascript">
  var viewModelA = {
     name: ko.observable("Bob")
  };

  var viewModelB = {
     name: ko.observable("Ted")
  };

  ko.applyBindings(viewModelA, document.getElementById("one"));
  ko.applyBindings(viewModelB, document.getElementById("two"));
</script>

ดังนั้นคุณสามารถใช้เทคนิคนี้เพื่อผูก viewModel กับเนื้อหาแบบไดนามิกที่คุณโหลดลงในกล่องโต้ตอบของคุณ โดยรวมแล้วคุณเพียง แต่ต้องระวังไม่ให้โทรapplyBindingsหลายครั้งในองค์ประกอบเดียวกันเนื่องจากคุณจะได้รับตัวจัดการเหตุการณ์หลายตัว


17
หากคุณต้องการลบการผูกในบางจุดที่ถนนคุณสามารถโทรko.cleanNode(document.getElementById("one")เพื่อล้างสิ่งต่างๆหรือko.removeNode(document.getElementById("one")ล้างข้อมูลและลบโหนดออกจาก DOM
Michael Berkompas

7
เพิ่งทราบว่าcleanNodeและremoveNodeจะไม่ลบตัวจัดการเหตุการณ์ดังนั้นใช้ความระมัดระวัง ในบางกรณีคุณควรใช้templateหรือwithเชื่อมโยงพื้นที่เหล่านั้นเพื่อให้คุณมีองค์ประกอบใหม่
RP Niemeyer

7
ขณะนี้เป็นสิ่งที่ขาดใน KO เราไม่ได้ตั้งใจจะให้คนส่วน "rebind" โดยเฉพาะ อย่างไรก็ตาม KO จะแนบเหตุการณ์โดยใช้ jQuery หากมีการอ้างอิงดังนั้นคุณสามารถทำได้$(element).unbind();เพื่อลบตัวจัดการทั้งหมด
RP Niemeyer

5
ฟังก์ชั่นเหล่านี้อยู่ที่ไหน (ApplyBindings, cleanNode, removeNode) ฉันไม่พบลายเซ็นการทำงานของพวกเขาใน knockoutjs.com
EricP

2
จะดีถ้านี่ที่ไหนสักแห่งหาได้ง่ายภายในเอกสาร ฉันไม่เห็นแม้แต่จะพูดถึงมัน
Travis Kaufman

61

ในขณะที่คำตอบของ Niemeyer เป็นคำตอบที่ถูกต้องมากกว่าสำหรับคำถามคุณสามารถทำสิ่งต่อไปนี้:

<div>
  <input data-bind="value: VMA.name" />
</div>

<div>
  <input data-bind="value: VMB.name" />
</div>

<script type="text/javascript">
  var viewModels = {
     VMA: {name: ko.observable("Bob")},
     VMB: {name: ko.observable("Ted")}
  };

  ko.applyBindings(viewModels);
</script>

ซึ่งหมายความว่าคุณไม่จำเป็นต้องระบุองค์ประกอบ DOM และคุณสามารถผูกหลายรุ่นเข้ากับองค์ประกอบเดียวกันได้ดังนี้

<div>
  <input data-bind="value: VMA.name() + ' and ' + VMB.name()" />
</div>

4
คุณยังสามารถใช้ "กับ" เพื่อจัดสรรพื้นที่ของหน้าให้กับแต่ละรุ่น - data-bind = "ด้วย: VMA"
lexicalscope

3
@flamingpenguin: ใช่ แต่withไม่ได้ราคาถูกดู: ลิงค์
mhu

7

ฉันจัดการผูกโมเดลที่กำหนดเองเข้ากับองค์ประกอบตอนรันไทม์ รหัสอยู่ที่นี่: http://jsfiddle.net/ZiglioNZ/tzD4T/457/

บิตที่น่าสนใจคือฉันใช้ data-bind attribute กับองค์ประกอบที่ฉันไม่ได้กำหนด:

    var handle = slider.slider().find(".ui-slider-handle").first();
    $(handle).attr("data-bind", "tooltip: viewModel.value");
    ko.applyBindings(viewModel.value, $(handle)[0]);

มีปัญหากับ ko 2.3 โค้ดข้างต้นอยู่ในตัวจัดการลูกค้าที่ถูกเรียกเมื่อฉันใช้ ko.applyBindings ทั่วโลก () ดังนั้นตอนนี้ฉันได้รับข้อผิดพลาด "คุณไม่สามารถใช้การผูกหลายครั้งกับองค์ประกอบเดียวกัน" ฉันยังคงพยายามหาสาเหตุที่ทำให้เกิดข้อผิดพลาด เราไม่สามารถใช้การเชื่อมโยงกับตัวแปรเดียวกันหลาย ๆ ครั้งได้หรือไม่กับแต่ละองค์ประกอบที่แตกต่างกัน?
ZiglioUK

นี่คือรุ่นที่มี ko 2.3 ที่ใช้งานไม่ได้: jsfiddle.net/ZiglioNZ/tzD4T/458
ZiglioUK

การเพิ่มการเรียกไปยัง ko.cleanNode () ก่อนการเรียกใช้การผูกเข้ากับมุมมองบางส่วนดูเหมือนจะไม่ช่วย: jsfiddle.net/ZiglioNZ/tzD4T/459
ZiglioUK

แก้ไขแล้ว: ฉันไม่จำเป็นต้องโทรสมัครใช้การผูก!
ZiglioUK

ive เพิ่งแก้ไขซอร์สโค้ด knockoutjs และคอมเม้นต์ส่วนที่ฟังก์ชั่น twrows "คุณไม่สามารถใช้การผูกหลายครั้งกับองค์ประกอบเดียวกันได้" ตอนนี้ทุกอย่างใช้ได้แล้ว ... ฉันรู้ว่านี่เป็นวิธีที่สกปรก แต่ฉันใหม่กับห้องสมุดดังนั้น ฉันไม่รู้ว่าจะไม่ใช้มันหลายครั้งสำหรับปัญหาของฉัน
Geomorillo

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.