AngularJS: ทำไม ng-bind จึงดีกว่า {{}} เป็นมุม?


401

ฉันเป็นหนึ่งในการนำเสนอเชิงมุมและหนึ่งในบุคคลที่กล่าวถึงการประชุมng-bindดีกว่า{{}}มีผลผูกพัน

เหตุผลข้อหนึ่งng-bindวางตัวแปรไว้ในรายการเฝ้าดูและเมื่อมีแบบจำลองที่เปลี่ยนแปลงข้อมูลที่ถูกผลักเพื่อดูในอีกทางหนึ่ง{{}}จะทำการสอดแทรกนิพจน์ทุกครั้ง (ฉันเดาว่ามันคือวงจรเชิงมุม) และกด ค่าแม้ว่าค่าจะเปลี่ยนแปลงหรือไม่

นอกจากนี้ยังมีการกล่าวว่าหากคุณมีข้อมูลไม่มากในหน้าจอคุณสามารถใช้งานได้{{}}และปัญหาด้านประสิทธิภาพจะไม่ปรากฏให้เห็น มีใครบ้างที่จะให้ความกระจ่างในเรื่องนี้กับฉันได้ไหม



3
คุณช่วยตรวจสอบได้ไหมถ้าคำตอบของฉันดีกว่า
Konstantin Krass

{{}} ในความคิดของฉันไม่เป็นประโยชน์ผู้ดูจะเห็นแท็กของคุณก่อนที่ข้อมูลจะถูกโหลดอย่างสมบูรณ์ ฉันสงสัยว่าทีม Angular จะแก้ไขปัญหานี้ได้หรือไม่
Jerry Liang

2
@Blazemonger: คุณไม่สามารถรวมแอ็ตทริบิวต์ ng-cloak เพื่อป้องกันไม่ให้แสดงเทมเพลตในขณะนี้ได้หรือไม่
supershnee

คำตอบ:


322

หากคุณไม่ได้ใช้ng-bindงานให้ทำดังนี้:

<div>
  Hello, {{user.name}}
</div>

คุณอาจเห็นค่าจริงHello, {{user.name}}เป็นวินาทีก่อนที่user.nameจะได้รับการแก้ไข (ก่อนที่ข้อมูลจะถูกโหลด)

คุณสามารถทำอะไรเช่นนี้

<div>
  Hello, <span ng-bind="user.name"></span>
</div>

ถ้านั่นเป็นปัญหาสำหรับคุณ

ng-cloakทางออกก็คือการใช้งาน


3
ขึ้นอยู่กับสิ่งที่คุณพูดไม่มีการตีประสิทธิภาพถ้าเราใช้ {{}}? มีคนบอกฉันว่าถ้าคุณใช้ {{}} ทุกครั้งที่จะได้รับผลรวมและสร้างผลลัพธ์แม้ว่าตัวแบบจะไม่เปลี่ยนแปลงก็ตาม
แนร์

4
และวิธีการใช้ ng-bind ถ้าฉันไม่ต้องการห่อ user.name ภายในแท็ก span? ถ้าฉันใช้วงเล็บปีกกาฉันจะได้ชื่อที่สะอาดโดยไม่มีแท็ก html
Victor

5
@KevinMeredith ดูเหมือนว่าเมื่อ HTML โหลดแล้ว แต่เชิงมุมยังไม่ได้ (ยัง) จำไว้ว่ามันเป็นการสร้างเทมเพลตฝั่งไคลเอ็นต์ที่เรากำลังพูดถึง การแก้ไขทั้งหมดจะต้องทำในเบราว์เซอร์ที่โหลดแอป โดยปกติแล้วมุมเชิงมุมจะโหลดเร็วพอที่จะไม่สังเกตเห็นได้ แต่ในบางกรณีมันจะกลายเป็นปัญหา ดังนั้นจึงng-cloakถูกคิดค้นขึ้นมาเพื่อแก้ไขปัญหานี้
หลักการโฮโลแกรม

17
สำหรับฉันนี่ไม่ใช่คำตอบของคำถามทำไม ngBind ถึงดีกว่า เป็นเพียงวิธีการใช้ ngBind แทนการเพิ่มความคิดเห็น {{}} และการอ้างอิงถึง ngCloak
Konstantin Krass

4
@Victor ยังมีng-bind-templateที่ที่คุณสามารถรวมทั้งสองวิธีเข้าด้วยกัน: ที่ng-bind-template="Hello, {{user.name}}"นี่การรวมยังเสนอการเพิ่มประสิทธิภาพและไม่แนะนำการทำรังเพิ่มเติม
loother

543

ทัศนวิสัย:

ในขณะที่เชิงมุมของคุณกำลัง bootstrapping ผู้ใช้อาจเห็นวงเล็บที่คุณวางไว้ใน html ng-cloakนี้สามารถจัดการกับ ng-bindแต่สำหรับผมนี่เป็นวิธีแก้ปัญหาที่ฉันไม่จำเป็นต้องใช้ถ้าผมใช้


ประสิทธิภาพ:

{{}}คือช้ามาก

นี่ng-bindเป็นคำสั่งและจะวาง watcher บนตัวแปรที่ส่งผ่าน ดังนั้นค่าng-bindจะถูกใช้เมื่อค่าที่ส่งผ่านเปลี่ยนไปจริง

ในทางกลับกันวงเล็บจะสกปรกตรวจสอบและรีเฟรชทุกครั้ง $digestแม้ว่าจะไม่จำเป็นก็ตาม


ขณะนี้ฉันกำลังสร้างแอปหน้าเว็บขนาดใหญ่ (ประมาณ 500 ครั้งต่อการดู) การเปลี่ยนจาก {{}} เป็นเข้มงวดng-bindช่วยให้เราประหยัดได้ถึง 20% ในทุกscope.$digest


คำแนะนำ :

หากคุณใช้โมดูลการแปลเช่นangular-translateเสมอชอบคำสั่งก่อนที่จะใส่คำอธิบายประกอบวงเล็บ

{{'WELCOME'|translate}} => <span ng-translate="WELCOME"></span>

หากคุณต้องการฟังก์ชั่นตัวกรองให้ใช้คำสั่งที่ดีกว่าซึ่งใช้ตัวกรองที่คุณกำหนดเอง เอกสารประกอบสำหรับบริการตัวกรอง $


อัปเดต 28.11.2014 (แต่อาจอยู่นอกหัวข้อ):

ใน Angular 1.3x มีbindonceการแนะนำการใช้งาน ดังนั้นคุณสามารถผูกค่าของนิพจน์ / แอตทริบิวต์หนึ่งครั้ง (จะถูกผูกไว้เมื่อ! = 'undefined')

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

สถานที่::ก่อนที่จะผูกพันของคุณ:

<ul>  
  <li ng-repeat="item in ::items">{{item}}</li>
</ul>  
<a-directive name="::item">
<span data-ng-bind="::value"></span>

ตัวอย่าง:

ng-repeatเพื่อส่งออกข้อมูลบางส่วนในตารางที่มีการผูกหลายต่อแถว การแปล - การเชื่อมโยง, กรองผลลัพธ์ที่ได้รับการดำเนินการในทุกขอบเขตการย่อย


32
นี่เป็นคำตอบที่ดีกว่า
NimChimpsky

13
จากสิ่งที่ฉันสามารถบอกได้จากแหล่งที่มา (ตั้งแต่ 2014-11-24) การแก้ไขแบบหยิกได้รับการจัดการเช่นเดียวกับคำสั่ง (ดู addTextInterpolateDirective () ใน ng / compile.js) นอกจากนี้ยังใช้ $ watch เพื่อให้ DOM ไม่ได้รับการสัมผัสหากข้อความไม่เปลี่ยนแปลงมันไม่ "ตรวจสอบและรีเฟรชสกปรก" ทุกครั้งที่คุณแยกย่อย สิ่งที่ทำในทุก ๆ สรุปย่อยของ $ แม้ว่าจะมีการคำนวณสตริงผลลัพธ์ที่ได้รับการแก้ไข มันไม่ได้ถูกกำหนดให้กับโหนดข้อความยกเว้นว่ามันจะเปลี่ยนแปลง
Matti Virkkunen

6
ฉันเขียนแบบทดสอบประสิทธิภาพสำหรับการประเมินผลภายใน มันมี 2,000 รายการในการทำซ้ำ ng และแสดงแอตทริบิวต์ 2 รายการในวัตถุดังนั้นการผูก 2000x2 การรวมที่แตกต่างกันใน: การผูกครั้งแรกเป็นเพียงการผูกในช่วง วินาทีมีผลผูกพันและ html ธรรมดาบางอย่างในนั้น ผลลัพธ์: ng-bind เร็วขึ้นประมาณ 20% ต่อขอบเขตที่ใช้ ดูเหมือนว่าไม่มีการตรวจสอบรหัสดูเหมือนว่า html ธรรมดาเพิ่มเติมที่มีนิพจน์หยิกในองค์ประกอบ html นั้นต้องใช้เวลามากขึ้น
Konstantin Krass

2
เพียงต้องการชี้ให้เห็นว่าตามการทดสอบที่นี่: jsperf.com/angular-bind-vs-bracketsดูเหมือนจะแสดงว่าวงเล็บเร็วกว่าการผูก (หมายเหตุ: แท่งคือ ops ต่อวินาทีดังนั้นจะดีกว่าอีกต่อไป) และเมื่อความเห็นก่อนหน้านี้ชี้ให้เห็นกลไกการดูของพวกเขาเหมือนกันในที่สุด
Warren

1
เนื่องจากคุณไม่ได้ให้แหล่งข้อมูลใด ๆ เลยฉันขอให้คุณ: ng-perf.com/2014/10/30/… "ng-bind เร็วขึ้นเพราะมันง่ายกว่าการแก้ไขต้องผ่านขั้นตอนพิเศษในการตรวจสอบบริบท ค่าและอื่น ๆ ที่ทำให้ช้าลงเล็กน้อย "
Konstantin Krass

29

ng-bind ดีกว่า {{...}}

ตัวอย่างเช่นคุณสามารถทำได้:

<div>
  Hello, {{variable}}
</div>

ซึ่งหมายความว่าข้อความทั้งหมดHello, {{variable}}ล้อมรอบด้วย<div>จะถูกคัดลอกและเก็บไว้ในหน่วยความจำ

ถ้าคุณทำสิ่งนี้แทน:

<div>
  Hello, <span ng-bind="variable"></span>
</div>

เฉพาะค่าของค่าจะถูกเก็บไว้ในหน่วยความจำและเชิงมุมจะลงทะเบียน watcher (การแสดงออกของนาฬิกา) ซึ่งประกอบด้วยตัวแปรเท่านั้น


7
ในทางกลับกัน DOM ของคุณลึกกว่า ในเอกสารขนาดใหญ่สิ่งนี้อาจส่งผลกระทบต่อประสิทธิภาพการแสดงผลทั้งนี้ขึ้นอยู่กับสิ่งที่คุณทำ
stephband

2
ใช่ฉันคิดแบบเดียวกับที่ @stephband ทำ หากคุณต้องการแสดงชื่อและนามสกุลเช่น ทำไมไม่แก้ไขเพียง? มันจะทำงานในลักษณะเดียวกันเพราะมันจะรันนาฬิกาเดียวกันใน 1 ไดเจสต์ ไลค์: <div> {{firstName}} {{lastName}} </div> == <div> <span ng-bind = "firstName"> </span> <span ng-bind = "lastName"> </ span> </div> .. และอันแรกดูดีกว่า ฉันคิดว่ามันขึ้นอยู่กับสิ่งที่คุณต้องการ แต่ในที่สุดพวกเขาทั้งสองมีข้อดีและข้อเสีย
pgarciacamou

3
<div ng-bind-template="{{ var1 }}, {{ var2}}"></div>เป็นทางเลือกแทน {{}} และฟังก์ชันเช่น ng-bind
northamerican

1
นี่ไม่ใช่แอปเปิ้ลกับแอปเปิ้ล - คุณกำลังแนะนำองค์ประกอบการขยายในหนึ่งและไม่อื่น ๆ ตัวอย่างที่มีจะเปรียบมากขึ้นในการng-bind<div>Hello, <span>{{variable}}</span></div>
iconoclast

15

โดยทั่วไปแล้วไวยากรณ์ที่เป็นสองเท่าสามารถอ่านได้โดยธรรมชาติและต้องการการพิมพ์ที่น้อยลง

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

สิ่งที่สำคัญมากก็คือเฉพาะใน index.html ของแอพเชิงมุมที่คุณสามารถยกเลิกการแสดงผล{{}}ได้ หากคุณกำลังใช้คำสั่งดังนั้นเทมเพลตจะไม่มีโอกาสที่จะเห็นว่าเพราะเชิงมุมแรกแสดงเทมเพลตและหลังจากผนวกเข้ากับ DOM


5
ที่น่าสนใจก็คือมันไม่เหมือนกัน ฉันไม่ได้รับผลลัพธ์ใน ng-bind = "anArrayViaFactory" vs {{anArrayViaFactory}} ฉันเจอปัญหานี้เมื่อพยายามที่จะแสดงผลการตอบสนองแบบ json ใน protoype jekyll แต่เนื่องจากความขัดแย้งกับ templating {{}} ที่คล้ายกันฉันถูกบังคับให้ใช้ ng-bind ng-bind ภายในบล็อก ng-repeat (รายการใน anArrayViaFactory) จะส่งออกค่า
eddywashere

5

{{...}}หมายถึงการผูกข้อมูลแบบสองทาง แต่ng-bindนั้นหมายถึงการผูกข้อมูลทางเดียว

การใช้ng-bindจะลดจำนวนผู้ดูในหน้าของคุณ ดังนั้นng ผูก{{...}}จะเร็วกว่า ดังนั้นถ้าคุณเพียงต้องการที่จะแสดงค่าและการปรับปรุงของตนและไม่ต้องการที่จะสะท้อนให้เห็นถึงการเปลี่ยนแปลงจาก UI กลับไปยังตัวควบคุมแล้วไปng ผูก สิ่งนี้จะเพิ่มประสิทธิภาพของหน้ากระดาษและลดเวลาในการโหลดหน้าเว็บ

<div>
  Hello, <span ng-bind="variable"></span>
</div>

4

เนื่องจาก{{}}คอมไพเลอร์เชิงมุมพิจารณาทั้งโหนดข้อความและเป็นพาเรนต์เนื่องจากมีความเป็นไปได้ที่จะรวม 2 {{}}โหนด ดังนั้นจึงมีตัวเชื่อมโยงเพิ่มเติมที่เพิ่มให้กับความเร็วในการโหลด แน่นอนว่ามีบางอย่างที่แตกต่างกันอย่างมาก แต่เมื่อคุณใช้สิ่งนี้ใน repeater จำนวนมากมันจะส่งผลกระทบในสภาพแวดล้อมรันไทม์ที่ช้าลง


2

ป้อนคำอธิบายรูปภาพที่นี่

เหตุผลที่ Ng-Bind ดีกว่าเพราะ

เมื่อหน้าของคุณไม่โหลดหรือเมื่ออินเทอร์เน็ตของคุณช้าหรือเมื่อเว็บไซต์ของคุณโหลดมาครึ่งหนึ่งคุณจะเห็นปัญหาประเภทนี้(ตรวจสอบภาพหน้าจอที่มีเครื่องหมายอ่าน)จะถูกเรียกขึ้นมาบนหน้าจอซึ่งแปลกประหลาดอย่างสมบูรณ์ เพื่อหลีกเลี่ยงเช่นนี้เราควรใช้ Ng-bind


1

NG-ผูกมีปัญหา too.When คุณพยายามใช้เชิงมุมฟิลเตอร์ , ขีด จำกัดหรือสิ่งอื่นที่คุณอาจจะสามารถมีปัญหาถ้าคุณใช้ng ผูก แต่ในกรณีอื่นng-bindจะดีกว่าในด้านUXเมื่อผู้ใช้เปิดหน้าเขา / เธอจะเห็น (10ms-100ms) ที่พิมพ์สัญลักษณ์ ( {{... }} ) นั่นคือเหตุผลที่ ng-bind ดีกว่า .


1

มีปัญหาบางอย่างที่ริบหรี่ใน {{}} เช่นเมื่อคุณรีเฟรชหน้าเว็บจากนั้นจะเห็นสแปมในระยะเวลาสั้น ๆ ดังนั้นเราควรใช้ ng-bind แทนการแสดงออกเพื่อแสดงข้อมูล


0

ng-bindก็ปลอดภัยกว่าเพราะมันหมายถึงhtmlสตริง

ตัวอย่างเช่น'<script on*=maliciousCode()></script>'จะแสดงเป็นสตริงและไม่ถูกดำเนินการ


0

อ้างอิงจาก Angular Doc:
เนื่องจากngBindเป็นคุณสมบัติองค์ประกอบจึงทำให้ผู้ใช้มองไม่เห็นการเชื่อมโยงในขณะที่หน้ากำลังโหลด ... มันเป็นความแตกต่างหลัก ...

โดยพื้นฐานจนกระทั่งองค์ประกอบdomไม่โหลดเราไม่สามารถมองเห็นได้และเนื่องจากngBindเป็นคุณลักษณะในองค์ประกอบจึงรอจนกระทั่ง doms เข้ามาเล่น ... รายละเอียดเพิ่มเติมด้านล่าง

ngBind
- สั่งในโมดูล ng ngBind แอตทริบิวต์บอกAngularJS

เพื่อแทนที่เนื้อหาข้อความขององค์ประกอบ HTML ที่ระบุไว้ที่มีค่าของนิพจน์ที่กำหนดและปรับปรุงเนื้อหาข้อความเมื่อค่าของว่าการเปลี่ยนแปลงการแสดงออก

โดยทั่วไปแล้วคุณไม่ได้ใช้ ngBind โดยตรงแต่คุณใช้มาร์กอัปแบบสองทางเช่น{{expression}}ซึ่งคล้ายกัน แต่ verbose น้อยกว่า

มันจะดีกว่าที่จะใช้ ngBind แทน {{expression}} ถ้าเบราว์เซอร์ถูกแสดงในชั่วขณะโดยเบราว์เซอร์ในสถานะดิบของมันก่อน AngularJS จะรวบรวมมัน เนื่องจาก ngBind เป็นคุณลักษณะองค์ประกอบจึงทำให้ผู้ใช้มองไม่เห็นการเชื่อมโยงในขณะที่หน้ากำลังโหลด

โซลูชั่นทางเลือกในการแก้ไขปัญหานี้จะใช้ngCloakสั่ง เยี่ยมชมที่นี่

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับngbindไปที่หน้านี้: https://docs.angularjs.org/api/ng/directive/ngBind

คุณสามารถทำสิ่งนี้เป็นแอตทริบิวต์ng-bind :

<div ng-bind="my.name"></div>

หรือทำการแก้ไขดังต่อไปนี้:

<div>{{my.name}}</div>

หรือด้วยวิธีนี้กับแอตทริบิวต์ ng-cloak ใน AngularJs:

<div id="my-name" ng-cloak>{{my.name}}</div>

งะหลีกเลี่ยงการกระพริบบนโดมและรอจนกว่าจะพร้อม! นี่เท่ากับแอตทริบิวต์ng-bind ...


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