Cách tốt nhất để áp dụng có điều kiện các thuộc tính trong AngularJS là gì?


296

Tôi cần có thể thêm ví dụ "có thể nội dung" vào các phần tử, dựa trên một biến boolean trên phạm vi.

Ví dụ sử dụng:

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

Sẽ dẫn đến contenteditable = true được thêm vào phần tử nếu $scope.editModeđược đặt thành true. Có một số cách dễ dàng để thực hiện hành vi thuộc tính giống như lớp ng này? Tôi đang xem xét viết một chỉ thị và chia sẻ nếu không.

Chỉnh sửa: Tôi có thể thấy rằng dường như có một số điểm tương đồng giữa chỉ thị attrs được đề xuất của tôi và ng-bind-attrs, nhưng nó đã bị xóa trong 1.0.0.rc3 , tại sao vậy?


2
Tôi đã không bắt gặp bất cứ điều gì như thế. Tôi bỏ phiếu làm điều đó! : D Có thể gửi nó cho dự án góc. Một cú pháp phù hợp hơn với lớp ng sẽ là tốt. ng-attr="expression".
Xesued

Tôi chắc chắn đang xem xét rằng có!
Kenneth Lynne

3
Điều này thực sự không giống với ngClass hoặc ngStyle vì chúng kiểm soát một thuộc tính duy nhất và bạn muốn kiểm soát bất kỳ thuộc tính nào . Tôi nghĩ sẽ tốt hơn nếu tạo ra một contentEditablechỉ thị.
Josh David Miller

@JoshDavidMiller +1 về điều đó. Tôi nghĩ rằng có một chút lợi ích để có thể kiểm soát bất kỳ thuộc tính nào, đặc biệt là xem xét sự phức tạp. Bạn có thể có các chỉ thị có điều kiện hành động trên một biến.
Umur Kontacı

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

Câu trả lời:


272

Tôi đang sử dụng cách sau để đặt điều kiện lớp attr khi lớp ng-class không thể được sử dụng (ví dụ: khi tạo kiểu SVG):

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

Cách tiếp cận tương tự sẽ làm việc cho các loại thuộc tính khác.

(Tôi nghĩ rằng bạn cần phải có Angular không ổn định mới nhất để sử dụng ng-attr-, tôi hiện đang ở 1.1.4)


97
Chỉ cần làm rõ câu trả lời này: Nếu bạn thêm tiền tố vào bất kỳ thuộc tính nàong-attr- , thì trình biên dịch sẽ loại bỏ tiền tố và thêm thuộc tính với giá trị của nó được liên kết với kết quả của biểu thức góc từ giá trị thuộc tính ban đầu.
Matthias

12
Theo tôi, nó dễ đọc hơn nếu bạn sử dụng toán tử ternary, với hỗ trợ được thêm vào 1.1.5. Điều đó sẽ giống như: {{someConditableExpression? 'class-when-true': 'class-when-false'}}
dshap

129
vấn đề với cách tiếp cận này là thuộc tính được tạo bất kể kết quả ra sao. Lý tưởng nhất là chúng ta muốn kiểm soát thời tiết hoặc không thuộc tính được tạo ra.
airtonix

24
Lưu ý rằng ng-attr- Stuff đã bị xóa khỏi Angular 1.2. Ansswer này không còn hiệu lực.
Judah Gabriel Himango

2
Bạn sai rồi. Dự án này github.com/codecapers/AngularJS-FlowChart sử dụng Angular 1.2 và ng-attr-. Ngoài ra các tài liệu mới nhất (Angular 1.4) vẫn bao gồm ng-attr-
Ashley Davis

120

Bạn có thể thêm các thuộc tính tiền tố ng-attrđể đánh giá một biểu thức Angular. Khi kết quả của các biểu thức không xác định, điều này sẽ loại bỏ giá trị khỏi thuộc tính.

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

Sẽ sản xuất (khi giá trị là sai)

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

Vì vậy, không sử dụng false vì điều đó sẽ tạo ra từ "false" làm giá trị.

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

Khi sử dụng thủ thuật này trong một chỉ thị. Các thuộc tính cho lệnh sẽ là sai nếu chúng thiếu một giá trị.

Ví dụ, ở trên sẽ là sai.

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

3
Tôi thích câu trả lời này. Tuy nhiên, tôi không nghĩ rằng nếu giá trị không được xác định, nó sẽ ẩn thuộc tính. Tôi có thể đang thiếu một cái gì đó, mặc dù. Vì vậy, kết quả đầu tiên sẽ là <a ng-attr-href=" đũa nbvalue || không xác định đã được dán lại href href> Xin chào thế giới </a>
Roman K

13
@RomanK hi, hướng dẫn sử dụng đó undefinedlà một trường hợp đặc biệt. "Khi sử dụng ngAttr, cờ allOrNoth của $ interpolate được sử dụng, do đó, nếu bất kỳ biểu thức nào trong chuỗi nội suy dẫn đến không xác định, thuộc tính sẽ bị xóa và không được thêm vào phần tử."
Phản ứng

9
Chỉ cần một lưu ý để hỗ trợ bất kỳ độc giả nào trong tương lai, hành vi 'không xác định' dường như đã được thêm vào trong Angular 1.3. Tôi đang sử dụng 1.2.27 và hiện phải IE8.
Adam Marshall

3
Để xác nhận thêm một số Angular 1.2.15 sẽ hiển thị href ngay cả khi giá trị không được xác định, có vẻ như hành vi không xác định bắt đầu trong Angular 1.3 như các trạng thái nhận xét ở trên.
Brian Ogden

Điều quan trọng cần lưu ý là ng-attr-foovẫn sẽ luôn luôn ra lệnh foonếu nó tồn tại, thậm chí ng-attr-foođánh giá undefined. thảo luận
hughes

97

Tôi đã làm việc này bằng cách thiết lập cứng thuộc tính. Và kiểm soát khả năng ứng dụng thuộc tính bằng cách sử dụng giá trị boolean cho thuộc tính.

Đây là đoạn mã:

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

Tôi hi vọng cái này giúp được.


Vì góc có thể phân tích biểu thức IIF, điều này hoạt động hoàn hảo để đánh giá trạng thái trong phạm vi hiện tại và đánh giá các giá trị dựa trên trạng thái đó.
mccainz 13/07/2015

22

Trong phiên bản mới nhất của Angular (1.1.5), chúng đã bao gồm một lệnh có điều kiện được gọi ngIf. Nó khác với ngShowngHideở chỗ các yếu tố không bị ẩn, nhưng hoàn toàn không được bao gồm trong DOM. Chúng rất hữu ích cho các thành phần tốn kém để tạo nhưng không được sử dụng:

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

32
Tôi tin rằng ng-if chỉ hoạt động ở cấp độ phần tử, nghĩa là bạn không thể chỉ định một điều kiện cho chỉ một thuộc tính của một phần tử.
Max Strater

3
Thật vậy, nhưng sau đó bạn có thể làm<h1 ng-if="editMode" contenteditable="true"><h1 ng-if="!editMode">
ByScripts

5
hãy cẩn thận, tuy nhiên, điều đó ng-iftạo ra một phạm vi mới.
Shimon Rachlenko

1
@ShimonRachlenko Đồng ý! Đây có thể là một nguồn lớn của sự nhầm lẫn và lỗi. ng-iftạo ra một phạm vi mới nhưng ng-showkhông. Sự không nhất quán này luôn là một điểm nhức nhối đối với tôi. Phản ứng lập trình phòng thủ cho vấn đề này là: "luôn liên kết với thứ gì đó có dấu chấm trong biểu thức" và nó sẽ không thành vấn đề.
Brian Genisio

Nếu bạn muốn thêm một thuộc tính thực sự là một lệnh, điều này hoạt động rất tốt. Xấu hổ về việc sao chép mã
Adam Marshall

16

Để có được một thuộc tính hiển thị một giá trị cụ thể dựa trên kiểm tra boolean hoặc bị bỏ qua hoàn toàn nếu kiểm tra boolean không thành công, tôi đã sử dụng như sau:

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

Ví dụ sử dụng:

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

Sẽ đầu ra <div class="itWasTest">hoặc <div>dựa trên giá trị củaparams.type


9

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

sẽ tạo khi isTrue = true: <h1 contenteditable="true">{{content.title}}</h1>

và khi isTrue = false: <h1>{{content.title}}</h1>


5
Điều gì xảy ra nếu tôi muốn một số thứ như <h1 contenteditable = "row">
SuperUberDuper

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

Đây nên là câu trả lời được chấp nhận. Kịch bản của tôi là<video ng-attr-autoplay="{{vm.autoplay || undefined}}" />
LucasM

6

Về giải pháp được chấp nhận, một giải pháp được đăng bởi Ashley Davis, phương thức được mô tả vẫn in thuộc tính trong DOM, bất kể thực tế là giá trị mà nó được gán là không xác định.

Ví dụ: trên thiết lập trường đầu vào có cả thuộc tính ng-model và thuộc tính value:

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

Bất kể những gì đằng sau myValue, giá trị thuộc tính vẫn được in trong DOM, do đó, được giải thích. Ng-model sau đó, trở nên bị ghi đè.

Một chút khó chịu, nhưng sử dụng ng-if thực hiện thủ thuật:

<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" />

Tôi sẽ khuyên bạn nên sử dụng kiểm tra chi tiết hơn bên trong các chỉ thị ng-if :)


Với phương pháp này, bạn sẽ lặp lại cùng một mã.
Kalyan

Đúng, nhưng nó giữ cho tuyên bố mô hình an toàn. Vấn đề của tôi khi sử dụng giải pháp được chấp nhận là thuộc tính value kết thúc trong DOM, được ưu tiên hơn so với khai báo mô hình. Vì vậy, nếu thuộc tính value là trống nhưng mô hình thì không, mô hình sẽ bị ghi đè để lấy giá trị trống.
alexc

6

Ngoài ra, bạn có thể sử dụng một biểu thức như thế này:

<h1 ng-attr-contenteditable="{{ editMode ? true : false }}"></h1>

5

Tôi thực sự đã viết một bản vá để làm điều này một vài tháng trước (sau khi có ai đó hỏi về nó trong #angularjs trên freenode).

Nó có thể sẽ không được hợp nhất, nhưng nó rất giống với ngClass: https://github.com/angular/angular.js/pull/4269

Cho dù nó có được hợp nhất hay không, công cụ ng-attr- * hiện tại có thể phù hợp với nhu cầu của bạn (như những người khác đã đề cập), mặc dù nó có thể hơi khó hiểu hơn chức năng kiểu ngClass mà bạn đang đề xuất.


2

Để xác thực trường đầu vào, bạn có thể làm:

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

Điều này sẽ áp dụng các thuộc tính maxđể 100chỉ khi discountTypeđược định nghĩa là%


1

Chỉnh sửa : Câu trả lời này có liên quan đến Angular2 +! Xin lỗi, tôi đã bỏ lỡ thẻ!

Câu trả lời gốc:

Đối với trường hợp rất đơn giản khi bạn chỉ muốn áp dụng (hoặc đặt) một thuộc tính nếu một giá trị Đầu vào nào đó được đặt, nó dễ như

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

Nó giống như:

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

(Vì vậy, tùy chọnValue được áp dụng nếu được đưa ra nếu không biểu thức là sai và thuộc tính không được áp dụng.)

Ví dụ: Tôi đã gặp trường hợp, trong đó tôi cho phép áp dụng một màu nhưng cũng có kiểu tùy ý, trong đó thuộc tính màu không hoạt động như đã được đặt (ngay cả khi màu @Input () không được cung cấp):

@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;
...
}

Vì vậy, "style.color" chỉ được đặt, khi thuộc tính màu ở đó, nếu không thì có thể sử dụng thuộc tính màu trong chuỗi "style".

Tất nhiên, điều này cũng có thể đạt được với

[style.color]="color" 

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

Angular.JS là Angular 1, rất khác so với Angular 2+. Câu trả lời giải pháp của bạn cho Angular 2+, nhưng AngularJS (1) đã được yêu cầu.
ssc-hrep3

@ ssc-hrep3: Bạn nói đúng. Xin lỗi tôi đã bỏ lỡ! Cảm ơn. Tôi chỉnh sửa câu trả lời để chỉ ra điều đó. :-)
Zaphoid

là angularjs không góc cạnh, angularjs là góc 1
dgzornoza

0

Chỉ trong trường hợp bạn cần giải pháp cho Angular 2 thì đơn giản, hãy sử dụng ràng buộc thuộc tính như bên dưới, ví dụ bạn muốn làm cho đầu vào chỉ đọc có điều kiện, sau đó thêm vào dấu ngoặc vuông theo dấu attrbute theo sau = dấu và biểu thức.

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

là angularjs (angular1) không angular (angular2)
dgzornoza

angular 2+ và Angular JS không giống nhau, chúng giống các sản phẩm khác nhau hoàn toàn.
Sanjay Singh

0

Đã có thể làm việc này:

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

Điều thú vị ở đây là nếu item.isSelected là false thì thuộc tính đơn giản là không được hiển thị.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.