điều kiện nội tuyến trong angular.js


192

Tôi đã tự hỏi liệu có cách nào để hiển thị nội dung một cách có điều kiện ngoài việc sử dụng ng-show, v.v. Ví dụ trong backbone.js tôi có thể làm gì đó với nội dung nội tuyến trong một mẫu như:

<% if (myVar === "two") { %> show this<% } %>

nhưng trong góc cạnh, tôi dường như bị giới hạn trong việc hiển thị và ẩn những thứ được bọc trong các thẻ html

<p ng-hide="true">I'm hidden</p>
<p ng-show="true">I'm shown</p>

Cách được đề xuất trong góc để hiển thị có điều kiện và ẩn nội dung nội tuyến trong góc chỉ sử dụng {{}} thay vì gói nội dung trong thẻ html là gì?


6
vui lòng không chấp nhận câu trả lời của tôi chấp nhận 2Toad's khi bạn có cơ hội.
Ben Lesh

Câu trả lời:


139

EDIT: Câu trả lời của 2Toad dưới đây là những gì bạn đang tìm kiếm! Nâng cao điều đó

Nếu bạn đang sử dụng Angular <= 1.1.4 thì câu trả lời này sẽ có:

Thêm một câu trả lời cho điều này. Tôi đang đăng một câu trả lời riêng biệt, bởi vì đó là một nỗ lực "chính xác" cho một giải pháp hơn là một danh sách các giải pháp có thể:

Đây là một bộ lọc sẽ thực hiện "ngay lập tức nếu" (còn gọi là iif):

app.filter('iif', function () {
   return function(input, trueValue, falseValue) {
        return input ? trueValue : falseValue;
   };
});

và có thể được sử dụng như thế này:

{{foo == "bar" | iif : "it's true" : "no, it's not"}}

Cảm ơn bạn, đây là những gì tôi sẽ làm. Tuy nhiên, tôi nhận thấy rằng nếu tôi cố gắng đặt một thẻ html vào một trong các giá trị thì nó sẽ phá vỡ: {{thing.second == "hai" | iif: "<ul class = 'hai-class'>": "<ul>"}} Tôi nhận ra rằng có thể có những cách tốt hơn để làm điều này trong góc, nhưng có cách nào để thoát "<" và ">" để các thẻ có thể được xuất ra như một phần của chuỗi?
dùng1469779

1
ngBind không cho phép xuất HTML, bạn muốn sử dụng ng-bind-html-không an toàn
Ben Lesh

Ví dụ về ng-binf-html-không an toàn trong tài liệu góc sử dụng nó trong thẻ, ví dụ <ANY ng-bind-html-unsafe = "{biểu thức}">. nó có thể không thể làm những gì tôi đang cố gắng làm nội tuyến.
dùng1469779

1
IIF là tên viết tắt của "Inline If". Nó phổ biến trong các ngôn ngữ lập trình khác nhau ... chỉ là không phổ biến như ?: Ifs nội tuyến. ;)
Ben Lesh

18
@BenLesh đạo cụ chính để chỉnh sửa câu trả lời của bạn bây giờ có các tùy chọn khác, hoạt động tốt.
Nick Coad

724

Angular 1.1.5 bổ sung hỗ trợ cho các nhà khai thác ternary:

{{myVar === "two" ? "it's true" : "it's false"}}

14
Câu trả lời này với hầu hết các câu trả lời sẽ xuất hiện ở đầu câu trả lời ... cho đến nay là đúng nhất
Code Whisperer

3
user1469779 xem xét chấp nhận câu trả lời này vì đây là cách được đề xuất để đạt được những gì bạn muốn trong một thời gian khá lâu
Filip Kis

13
@ 2Toad, câu trả lời của tôi đã cũ. Bây giờ đây là câu trả lời đúng, tôi không biết liệu người dùng có quay lại "chấp nhận" ngay bây giờ không, nhưng tôi đã chú thích câu trả lời của mình như vậy. Đó là bộ mặt thay đổi của phát triển phần mềm.
Ben Lesh

2
Cảm ơn. Làm thế nào tôi có thể có nó hiển thị giá trị myVarchỉ khi nó là sai? (tức là làm thế nào tôi có thể lồng các biến trong biểu thức?) Tôi đã thử {{myVar === "two" ? "it's true" : {{myVar}}}}nhưng nó không hoạt động.
Josh

6
@Josh myVartài sản không cần phải được bọc trong các dấu ngoặc nhọn bổ sung, nó đã nằm trong một biểu thức. Hãy thử{{myVar === "two" ? "it's true" : myVar}}
2Toad

60

Hàng ngàn cách để da mèo này. Tôi nhận ra rằng bạn đang hỏi về {{}} một cách cụ thể, nhưng đối với những người khác đến đây, tôi nghĩ rằng đáng để hiển thị một số tùy chọn khác.

hoạt động trên phạm vi $ của bạn (IMO, đây là đặt cược tốt nhất của bạn trong hầu hết các tình huống):

  app.controller('MyCtrl', function($scope) {
      $scope.foo = 1;

      $scope.showSomething = function(input) {
           return input == 1 ? 'Foo' : 'Bar';
      };
   });

 <span>{{showSomething(foo)}}</span>

ng-show và ng-ẩn tất nhiên:

 <span ng-show="foo == 1">Foo</span><span ng-hide="foo == 1">Bar</span>

ngSwitch

 <div ng-switch on="foo">
   <span ng-switch-when="1">Foo</span>
   <span ng-switch-when="2">Bar</span>
   <span ng-switch-default>What?</span>
 </div>

Một bộ lọc tùy chỉnh như Bertrand đề xuất. (đây là lựa chọn tốt nhất của bạn nếu bạn phải làm điều tương tự lặp đi lặp lại)

app.filter('myFilter', function() {
   return function(input) {
     return input == 1 ? 'Foo' : 'Bar';
   }
}

{{foo | myFilter}}

Hoặc một lệnh tùy chỉnh:

app.directive('myDirective', function() {
   return {
     restrict: 'E',
     replace: true,
     link: function(scope, elem, attrs) {
       scope.$watch(attrs.value, function(v) {
          elem.text(v == 1 ? 'Foo': 'Bar');
       });
     }
   };
});


<my-directive value="foo"></my-directive>

Cá nhân, trong hầu hết các trường hợp tôi sử dụng một chức năng trong phạm vi của mình, nó sẽ giữ cho việc đánh dấu khá sạch sẽ và thực hiện nhanh chóng và dễ dàng. Trừ khi, đó là, bạn sẽ làm điều tương tự lặp đi lặp lại, trong trường hợp đó tôi sẽ đi với đề xuất của Bertrand và tạo một bộ lọc hoặc có thể là một chỉ thị, tùy thuộc vào hoàn cảnh.

Như mọi khi, điều quan trọng nhất là giải pháp của bạn rất dễ bảo trì và hy vọng có thể kiểm tra được. Và điều đó sẽ phụ thuộc hoàn toàn vào tình huống cụ thể của bạn.


18

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)

Tôi đã xuất bản một bài viết về làm việc với AngularJS + SVG nói về vấn đề này và các vấn đề liên quan. http://www.codeproject.com/Articles/709340/Imcellenceing-a-Flowchart-with-SVG-and-AngularJS


15

Để kiểm tra nội dung biến và có văn bản mặc định, bạn có thể sử dụng:

<span>{{myVar || 'Text'}}</span>

1
cảm ơn bạn! Tôi đã thử điều này nhưng tôi bỏ lỡ các trích dẫn xung quanh chuỗi :-)
Simona Adriani

Vì bất kỳ lý do gì, cú pháp này không hoạt động bằng cách sử dụng các ràng buộc một lần .. {{:: myVar | | 'Văn bản'}} sẽ không hoạt động. Phải không có ::
aoakeson

3

Nếu tôi hiểu bạn rõ tôi nghĩ bạn có hai cách để làm điều đó.

Trước tiên, bạn có thể thử ngSwitch và cách thứ hai có thể là tạo bộ lọc của riêng bạn . Có lẽ ngSwitch là aproach đúng nhưng nếu bạn muốn ẩn hoặc hiển thị nội dung nội tuyến, chỉ cần sử dụng bộ lọc {{}} là cách tốt nhất.

Dưới đây là một câu đố với một bộ lọc đơn giản làm ví dụ.

<div ng-app="exapleOfFilter">
  <div ng-controller="Ctrl">
    <input ng-model="greeting" type="greeting">
      <br><br>
      <h1>{{greeting|isHello}}</h1>
  </div>
</div>

angular.module('exapleOfFilter', []).
  filter('isHello', function() {
    return function(input) {
      // conditional you want to apply
      if (input === 'hello') {
        return input;
      }
      return '';
    }
  });

function Ctrl($scope) {
  $scope.greeting = 'hello';
}

3

Thư viện UI góc có tích hợp chỉ thị ui-if cho điều kiện trong mẫu / Lượt xem tối đa góc ui 1.1.4

Ví dụ: Hỗ trợ trong giao diện người dùng góc tới tối đa 1.1.4

<div ui-if="array.length>0"></div>

ng-nếu có trong tất cả các phiên bản góc sau 1.1.4

<div ng-if="array.length>0"></div>

Nếu bạn có bất kỳ dữ liệu nào trong biến mảng thì chỉ có div sẽ xuất hiện


ui-ifđã bị xóa ít nhất khỏi phiên bản mới nhất angular-ui nhưng vì góc 1.1.5 mà bạn có ng-if(từ nhận xét này )
Dave Everitt

2

Vì vậy, với Angular 1.5.1 (đã có sự phụ thuộc ứng dụng hiện có vào một số phụ thuộc ngăn xếp MEAN khác là lý do tại sao tôi hiện không sử dụng 1.6.4)

Điều này làm việc cho tôi như OP nói {{myVar === "two" ? "it's true" : "it's false"}}

{{vm.StateName === "AA" ? "ALL" : vm.StateName}}

2

nếu bạn muốn hiển thị "Không" khi giá trị là "0", bạn có thể sử dụng như:

<span> {{ $scope.amount === "0" ?  $scope.amount : "None" }} </span>

hoặc sai trong js góc

<span> {{ $scope.amount === "0" ?  "False" : "True" }} </span>

1

Hoạt động ngay cả trong các tình huống kỳ lạ:

<br ng-show="myCondition == true" />

0

Tôi sẽ ném của tôi trong hỗn hợp:

https://gist.github.com/btm1/6802312

điều này đánh giá câu lệnh if một lần và không thêm trình nghe xem NHƯNG bạn có thể thêm một thuộc tính bổ sung cho phần tử có tập hợp-if được gọi là Wait-for = "somedata.prop" và nó sẽ đợi dữ liệu hoặc thuộc tính đó được đặt trước đánh giá câu lệnh if một lần. thuộc tính bổ sung đó có thể rất tiện dụng nếu bạn đang chờ dữ liệu từ yêu cầu XHR.

angular.module('setIf',[]).directive('setIf',function () {
    return {
      transclude: 'element',
      priority: 1000,
      terminal: true,
      restrict: 'A',
      compile: function (element, attr, linker) {
        return function (scope, iterStartElement, attr) {
          if(attr.waitFor) {
            var wait = scope.$watch(attr.waitFor,function(nv,ov){
              if(nv) {
                build();
                wait();
              }
            });
          } else {
            build();
          }

          function build() {
            iterStartElement[0].doNotMove = true;
            var expression = attr.setIf;
            var value = scope.$eval(expression);
            if (value) {
              linker(scope, function (clone) {
                iterStartElement.after(clone);
                clone.removeAttr('set-if');
                clone.removeAttr('wait-for');
              });
            }
          }
        };
      }
    };
  });
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.