อะไรคือวิธีที่ดีที่สุดในการใช้คุณสมบัติตามเงื่อนไขใน AngularJS


296

ฉันต้องสามารถเพิ่มตัวอย่างเช่น "contenteditable" เพื่อองค์ประกอบขึ้นอยู่กับตัวแปรบูลีนในขอบเขต

ตัวอย่างการใช้:

<h1 attrs="{'contenteditable=\"true\"': editMode}">{{content.title}}</h1>

จะส่งผลให้ contenteditable = true ถูกเพิ่มเข้ากับองค์ประกอบหาก$scope.editModeถูกตั้งค่าเป็นtrueถูกกำหนดให้มีวิธีง่าย ๆ ในการใช้ ng-class เช่นลักษณะการทำงานของคุณลักษณะ? ฉันกำลังพิจารณาที่จะเขียนคำสั่งและการแบ่งปันหากไม่ได้

แก้ไข: ฉันเห็นว่ามีความคล้ายคลึงกันระหว่างคำสั่ง attrs ที่ฉันเสนอกับng-bind-attrs แต่มันถูกลบใน 1.0.0.rc3ทำไม?


2
ฉันไม่ได้เจออะไรแบบนั้น ฉันลงคะแนนทำมัน! : D อาจส่งไปยังโครงการเชิงมุม ไวยากรณ์ที่ตรงกับ ng-class ดีกว่าจะดี ng-attr="expression".
Xesued

ฉันกำลังพิจารณาอย่างแน่นอนว่าใช่!
Kenneth Lynne

3
สิ่งนี้ไม่เหมือนกับ ngClass หรือ ngStyle เพราะมันควบคุมคุณสมบัติเดียวและคุณต้องการควบคุมคุณลักษณะใด ๆ ฉันคิดว่ามันจะเป็นการดีกว่าที่จะสร้างcontentEditableคำสั่ง
Josh David Miller

@JoshDavidMiller +1 บนนั้น ฉันคิดว่ามีประโยชน์เล็กน้อยที่จะสามารถควบคุมคุณลักษณะใด ๆ โดยเฉพาะการพิจารณาความซับซ้อน คุณสามารถมีไดเรกทีฟสั่งทำตามเงื่อนไข
อายุKontacı

<h1 ng-attr-contenteditable="{{editMode && true : false}}">{{content.title}}</h1>
mia

คำตอบ:


272

ฉันใช้สิ่งต่อไปนี้เพื่อตั้งค่า class attr แบบไม่มีเงื่อนไขเมื่อไม่สามารถใช้ ng-class ได้ (ตัวอย่างเช่นเมื่อใส่สไตล์ SVG):

ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}"

วิธีการเดียวกันควรใช้กับประเภทแอตทริบิวต์อื่น ๆ

(ฉันคิดว่าคุณต้องเป็น Angular ที่ไม่เสถียรล่าสุดเพื่อใช้ ng-attr- ตอนนี้ฉันใช้ 1.1.4)


97
เพียงชี้แจงคำตอบนี้: หากคุณใส่คำนำหน้าคุณลักษณะใด ๆng-attr-ไว้คอมไพเลอร์จะตัดส่วนนำหน้าออกและเพิ่มแอตทริบิวต์ด้วยค่าที่ผูกกับผลลัพธ์ของนิพจน์เชิงมุมจากค่าแอตทริบิวต์ดั้งเดิม
แมทเทียส

12
ในความคิดของฉันอ่านได้ง่ายขึ้นถ้าคุณใช้ผู้ประกอบการที่ประกอบไปด้วยสามส่วนซึ่งเพิ่มการสนับสนุนใน 1.1.5 นั่นจะมีลักษณะ: {{someConditional Expression? 'class-when-true': 'class-when-false'}}
dshap

129
ปัญหาของวิธีนี้คือการสร้างแอททริบิวต์โดยไม่คำนึงถึงผลลัพธ์ เป็นการดีที่เราต้องการควบคุมว่าจะสร้างแอตทริบิวต์ไม่ได้เลย
airtonix

24
โปรดทราบว่า ng-attr- stuff ถูกลบออกจาก Angular 1.2 คำตอบนี้ไม่ถูกต้องอีกต่อไป
ยูดาห์กาเบรียล Himango

2
คุณผิด. โครงการนี้github.com/codecapers/AngularJS-FlowChartใช้ Angular 1.2 และ ng-attr- นอกจากนี้เอกสารล่าสุด (Angular 1.4) ยังรวม ng-attr-
Ashley Davis

120

คุณสามารถใส่คำนำหน้าแอตทริบิวต์ด้วยng-attrเพื่อประเมินนิพจน์เชิงมุม เมื่อผลลัพธ์ของนิพจน์ไม่ได้กำหนดจะเป็นการลบค่าออกจากแอททริบิวต์

<a ng-attr-href="{{value || undefined}}">Hello World</a>

จะผลิต (เมื่อค่าเป็นเท็จ)

<a ng-attr-href="{{value || undefined}}" href>Hello World</a>

ดังนั้นอย่าใช้ falseเพราะจะทำให้คำว่า "เท็จ" เป็นค่า

<a ng-attr-href="{{value || false}}" href="false">Hello World</a>

เมื่อใช้เคล็ดลับนี้ในคำสั่ง คุณลักษณะสำหรับคำสั่งจะเป็นเท็จหากไม่มีค่า

ตัวอย่างข้างต้นจะเป็นเท็จ

function post($scope, $el, $attr) {
      var url = $attr['href'] || false;
      alert(url === false);
}

3
ฉันชอบคำตอบนี้ อย่างไรก็ตามฉันไม่คิดว่าหากค่าไม่ได้กำหนดจะซ่อนแอตทริบิวต์ ฉันอาจจะพลาดอะไรซักอย่าง ดังนั้นผลลัพธ์แรกจะเป็น <a ng-attr-href="{{value || undefined}}" href> Hello World </a>
Roman K

13
@ RomanK hi, คู่มือระบุว่าundefinedเป็นกรณีพิเศษ "เมื่อใช้ ngAttr จะใช้แฟล็ก allOrNothing ของ $ interpolate ดังนั้นหากนิพจน์ใด ๆ ในสตริงที่สอดแทรกนั้นส่งผลให้ไม่ได้กำหนดแอ็ตทริบิวต์จะถูกลบออกและไม่ได้เพิ่มลงในองค์ประกอบ"
Reactgular

9
เพียงบันทึกเพื่อช่วยให้ผู้อ่านในอนาคตใด ๆ พฤติกรรม 'ไม่ได้กำหนด' ดูเหมือนจะได้รับการเพิ่มใน Angular 1.3 ฉันใช้ 1.2.27 และปัจจุบันต้องใช้ IE8
Adam Marshall เมื่อ

3
หากต้องการยืนยันเพิ่มเติม Angular 1.2.15 จะแสดง href แม้ว่าค่าจะไม่ได้กำหนดดูเหมือนว่าพฤติกรรมที่ไม่ได้กำหนดจะเริ่มขึ้นใน Angular 1.3 เนื่องจากสถานะความคิดเห็นด้านบน
Brian Ogden

มันเป็นสิ่งสำคัญที่จะทราบว่าng-attr-fooจะยังคงอยู่เสมอเรียกfooคำสั่งถ้ามันมีอยู่แม้จะประเมินng-attr-foo การสนทนาundefined
hughes

97

ฉันได้รับการทำงานโดยการตั้งค่าคุณลักษณะอย่างหนัก และการควบคุมการบังคับใช้คุณสมบัติโดยใช้ค่าบูลีนสำหรับแอตทริบิวต์

นี่คือข้อมูลโค้ด:

<div contenteditable="{{ condition ? 'true' : 'false'}}"></div>

ฉันหวังว่านี่จะช่วยได้.


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

22

ในรุ่นล่าสุดของเชิงมุม (1.1.5) ngIfพวกเขาได้รวมคำสั่งเงื่อนไขที่เรียกว่า มันแตกต่างจากngShowและngHideในที่องค์ประกอบจะไม่ถูกซ่อน แต่ไม่รวมอยู่ใน DOM เลย มันมีประโยชน์มากสำหรับส่วนประกอบที่มีค่าใช้จ่ายสูงในการสร้าง แต่ไม่ได้ใช้:

<h1 ng-if="editMode" contenteditable=true>{{content.title}}</h1>

32
ฉันเชื่อว่า ng-if ใช้ได้กับระดับองค์ประกอบเท่านั้นนั่นคือคุณไม่สามารถระบุเงื่อนไขให้กับหนึ่งคุณลักษณะขององค์ประกอบ
Max Strater

3
แน่นอน แต่คุณสามารถทำได้<h1 ng-if="editMode" contenteditable="true"><h1 ng-if="!editMode">
ByScripts

5
อย่างไรก็ตามระวังที่ng-ifสร้างขอบเขตใหม่
Shimon Rachlenko

1
@ShimonRachlenko เห็นด้วย! นี่อาจเป็นแหล่งใหญ่ของความสับสนและข้อบกพร่อง ng-ifสร้างขอบเขตใหม่ แต่ng-showไม่ ความไม่ลงรอยกันนี้เป็นจุดที่เจ็บอยู่เสมอสำหรับฉัน ปฏิกิริยาการตั้งโปรแกรมการป้องกันต่อสิ่งนี้คือ: "ผูกกับสิ่งที่เป็นจุดในนิพจน์เสมอ" และมันจะไม่เป็นปัญหา
Brian Genisio

หากคุณต้องการเพิ่มคุณสมบัติที่เป็นจริงคำสั่งนี้ใช้งานได้ดี ความอับอายเกี่ยวกับการทำสำเนารหัส
Adam Marshall

16

ในการรับแอตทริบิวต์เพื่อแสดงค่าเฉพาะตามการตรวจสอบบูลีนหรือถูกละเว้นทั้งหมดหากการตรวจสอบบูลีนล้มเหลวฉันใช้ต่อไปนี้:

ng-attr-example="{{params.type == 'test' ? 'itWasTest' : undefined }}"

ตัวอย่างการใช้งาน:

<div ng-attr-class="{{params.type == 'test' ? 'itWasTest' : undefined }}">

จะส่งออก<div class="itWasTest">หรือ<div>ตามมูลค่าของparams.type


9

<h1 ng-attr-contenteditable="{{isTrue || undefined }}">{{content.title}}</h1>

จะผลิตเมื่อ isTrue = จริง: <h1 contenteditable="true">{{content.title}}</h1>

และเมื่อ isTrue = false: <h1>{{content.title}}</h1>


5
ถ้าฉันต้องการบางอย่างเช่น <h1 contenteditable = "row">
SuperUberDuper

<h1 ng-attr-contenteditable="{{isTrue ? 'row' : undefined}}">{{content.title}} </h1>
PhatBuck

นี่ฉันควรจะเป็นคำตอบที่ได้รับการยอมรับ สถานการณ์ของฉันคือ<video ng-attr-autoplay="{{vm.autoplay || undefined}}" />
LucasM

6

เกี่ยวกับโซลูชันที่ยอมรับวิธีการที่โพสต์โดย Ashley Davis วิธีที่อธิบายยังคงพิมพ์แอตทริบิวต์ใน DOM โดยไม่คำนึงถึงความจริงที่ว่าค่าที่ได้รับมอบหมายนั้นไม่ได้กำหนด

ตัวอย่างเช่นในการตั้งค่าฟิลด์อินพุตที่มีทั้ง ng-model และ attribute value

<input type="text" name="myInput" data-ng-attr-value="{{myValue}}" data-ng-model="myModel" />

โดยไม่คำนึงถึงสิ่งที่อยู่เบื้องหลัง myValue คุณค่าแอตทริบิวต์ยังคงได้รับการพิมพ์ใน DOM ดังนั้นตีความ จากนั้นนางแบบของ Ng จะกลายเป็นคนแทนที่

ค่อนข้างไม่เป็นที่พอใจ แต่การใช้ ng-if จะหลอกลวง:

<input type="text" name="myInput" data-ng-if="value" data-ng-attr-value="{{myValue}}" data-ng-model="myModel" />
<input type="text" name="myInput" data-ng-if="!value" data-ng-model="myModel" />

ฉันอยากจะแนะนำให้ใช้การตรวจสอบรายละเอียดเพิ่มเติมภายในคำสั่ง ng-if :)


ด้วยวิธีการนี้คุณจะทำซ้ำรหัสเดียวกัน
Kalyan

จริง แต่มันทำให้การประกาศโมเดลปลอดภัย ปัญหาของฉันในการใช้โซลูชันที่ยอมรับคือแอตทริบิวต์ value สิ้นสุดใน DOM โดยมีความสำคัญเหนือกว่าการประกาศแบบจำลอง ดังนั้นหากค่าแอททริบิวต์ว่างเปล่า แต่โมเดลไม่ใช่โมเดลจะถูกแทนที่เพื่อใช้ค่าว่าง
alexc


5

ฉันจริง ๆ เขียนโปรแกรมแก้ไขการทำเช่นนี้ไม่กี่เดือนที่ผ่านมา (หลังจากมีคนถามเกี่ยวกับมันใน #angularjs บน freenode)

มันอาจจะไม่ถูกผสาน แต่คล้ายกับ ngClass: https://github.com/angular/angular.js/pull/4269

ไม่ว่ามันจะถูกผสานหรือไม่ก็ตามสิ่งที่มีอยู่ใน ng-attr- * นั้นน่าจะเหมาะกับความต้องการของคุณ (ตามที่คนอื่น ๆ พูดถึง) แม้ว่ามันอาจจะฟังดูแปลก ๆ มากกว่าฟังก์ชั่นสไตล์ ngClass ที่คุณแนะนำ


2

สำหรับการตรวจสอบฟิลด์อินพุตคุณสามารถทำได้:

<input ng-model="discount" type="number" ng-attr-max="{{discountType == '%' ? 100 : undefined}}">

นี้จะนำไปใช้แอตทริบิวต์maxการ100เฉพาะในกรณีที่discountTypeถูกกำหนดให้เป็น%


1

แก้ไข : คำตอบนี้เกี่ยวข้องกับ Angular2 +! ขออภัยฉันพลาดแท็ก!

คำตอบเดิม:

สำหรับกรณีที่ง่ายมากเมื่อคุณต้องการใช้ (หรือตั้งค่า) แอททริบิวหากมีการตั้งค่าอินพุตบางอย่างมันก็ง่ายเหมือน

<my-element [conditionalAttr]="optionalValue || false">

มันเหมือนกับ:

<my-element [conditionalAttr]="optionalValue ? optionalValue : false">

(ดังนั้น optionalValue จะถูกนำไปใช้หากได้รับเป็นอย่างอื่นนิพจน์เป็นเท็จและไม่ได้ใช้แอตทริบิวต์)

ตัวอย่าง: ฉันมีกรณีที่ฉันปล่อยให้ใช้สี แต่ยังมีรูปแบบโดยพลการซึ่งคุณลักษณะสีไม่ทำงานตามที่ตั้งค่าไว้แล้ว (แม้ว่าจะไม่มีการระบุสี @Input ()):

@Component({
  selector: "rb-icon",
  styleUrls: ["icon.component.scss"],
  template: "<span class="ic-{{icon}}" [style.color]="color==color" [ngStyle]="styleObj" ></span>",
})
export class IconComponent {
   @Input() icon: string;
   @Input() color: string;
   @Input() styles: string;

   private styleObj: object;
...
}

ดังนั้น "style.color" จึงถูกตั้งค่าไว้เท่านั้นเมื่อแอตทริบิวต์ color อยู่ที่นั่นมิฉะนั้นจะสามารถใช้แอตทริบิวต์ color ในสตริง "styles" ได้

แน่นอนว่าสิ่งนี้สามารถทำได้ด้วย

[style.color]="color" 

และ

@Input color: (string | boolean) = false;

Angular.JS คือ Angular 1 ซึ่งแตกต่างจาก Angular 2+ มาก คำตอบการแก้ปัญหาของคุณสำหรับ Angular 2+ แต่ถูกถาม AngularJS (1)
ssc-hrep3

@ ssc-hrep3: คุณพูดถูก ขอโทษฉันพลาด! ขอบคุณ ฉันแก้ไขคำตอบเพื่อชี้ว่า :-)
Zaphoid

คือ angularjs ไม่เชิงมุม, angularjs is angular 1
dgzornoza

0

ในกรณีที่คุณต้องการวิธีแก้ปัญหาสำหรับ Angular 2 แล้วให้ใช้การผูกคุณสมบัติแบบด้านล่างเช่นคุณต้องการให้อินพุตอ่านอย่างเดียวแบบมีเงื่อนไขแล้วเพิ่มวงเล็บปีกกาที่ attrbute ตามด้วยเครื่องหมาย = และนิพจน์

<input [readonly]="mode=='VIEW'"> 

is angularjs (angular1) ไม่ใช่เชิงมุม (angular2)
dgzornoza

angular 2+ และ Angular JS ไม่เหมือนกันพวกมันเหมือนผลิตภัณฑ์ที่แตกต่างกันโดยสิ้นเชิง
Sanjay Singh

0

สามารถทำงานนี้ได้:

ng-attr-aria-current="{{::item.isSelected==true ? 'page' : undefined}}"

สิ่งที่ดีที่นี่คือถ้า item.isSelected เป็นเท็จแล้วแอตทริบิวต์ก็จะไม่แสดงผล

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