conditional inline dalam angular.js

192

Saya bertanya-tanya apakah ada cara di sudut untuk menampilkan konten selain menggunakan ng-show dll. Misalnya di backbone.js saya bisa melakukan sesuatu dengan konten inline dalam template seperti:

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

tetapi dalam sudut, saya tampaknya terbatas untuk menunjukkan dan menyembunyikan hal-hal yang dibungkus dengan tag html

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

Apa cara yang disarankan dalam sudut untuk menunjukkan dan menyembunyikan konten sebaris secara kondisional hanya menggunakan {{}} daripada membungkus konten dalam tag html?

pengguna1469779
sumber
6
tolong terima jawaban saya dan terima 2Toad ketika Anda mendapat kesempatan.
Ben Lesh

Jawaban:

139

Sunting : Jawaban 2Toad di bawah ini adalah yang Anda cari! Suara positif hal itu

Jika Anda menggunakan Angular <= 1.1.4 maka jawaban ini akan membantu:

Satu jawaban lagi untuk ini. Saya memposting jawaban terpisah, karena ini lebih merupakan upaya "tepat" pada solusi daripada daftar solusi yang mungkin:

Berikut filter yang akan melakukan "segera jika" (alias iif):

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

dan bisa digunakan seperti ini:

{{foo == "bar" | iif : "it's true" : "no, it's not"}}
Ben Lesh
sumber
Terima kasih blesh, inilah tujuan saya. Namun saya perhatikan bahwa jika saya mencoba untuk meletakkan tag html di salah satu nilai yang rusak: {{thing.second == "two" | iif: "<ul class = 'two-class'>": "<ul>"}} Saya menyadari bahwa mungkin ada cara yang lebih baik untuk melakukan ini dalam sudut, tetapi apakah ada cara untuk melarikan diri "<" dan ">" sehingga tag dapat di-output sebagai bagian dari string?
user1469779
1
ngBind tidak mengizinkan keluaran HTML, Anda ingin menggunakan ng-bind-html-unsafe
Ben Lesh
Contoh ng-binf-html-tidak aman dalam dokumentasi sudut menggunakannya dalam tag, misalnya <APA PUN ng-bind-html-unsafe = "{ekspresi}">. mungkin tidak mungkin melakukan apa yang saya coba lakukan sebaris.
user1469779
1
IIF adalah singkatan untuk "Inline If". Ini umum dalam bahasa pemrograman yang berbeda ... hanya saja tidak seperti?: Inline ifs. ;)
Ben Lesh
18
@BenLesh alat peraga utama untuk mengedit jawaban Anda sekarang karena ada opsi lain, kerja bagus.
Nick Coad
724

1.1.5 ditambahkan dukungan sudut untuk operator ternary:

{{myVar === "two" ? "it's true" : "it's false"}}
2Muat
sumber
14
Jawaban ini dengan paling upvotes akan muncul di bagian atas jawaban ... sejauh ini yang paling benar
Code Whisperer
3
user1469779 pertimbangkan untuk menerima jawaban ini karena ini adalah cara yang disarankan untuk mencapai apa yang Anda inginkan untuk beberapa waktu
Filip Kis
13
@ 2Toad, jawaban saya sudah tua. ini adalah jawaban yang benar sekarang, saya tidak tahu apakah pengguna akan kembali untuk "menerimanya" sekarang, tetapi saya sudah menjelaskan jawaban saya. Itulah wajah perubahan pengembangan perangkat lunak.
Ben Lesh
2
Terima kasih. Bagaimana saya bisa menampilkan nilai myVarhanya jika itu salah? (yaitu, bagaimana saya bisa membuat variabel sarang dalam ekspresi?) Saya mencoba {{myVar === "two" ? "it's true" : {{myVar}}}}tetapi tidak berhasil.
Josh
6
@Josh myVarproperti tidak perlu dibungkus dengan kurung kurawal tambahan, itu sudah ada di dalam ekspresi. Coba{{myVar === "two" ? "it's true" : myVar}}
2Muat
60

Ribuan cara menguliti kucing ini. Saya sadar Anda bertanya tentang antara {{}} secara khusus, tetapi untuk orang lain yang datang ke sini, saya pikir ada baiknya menampilkan beberapa opsi lain.

berfungsi pada $ scope Anda (IMO, ini adalah taruhan terbaik Anda di sebagian besar skenario):

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

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

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

ng-show dan ng-hide tentu saja:

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

Filter kustom seperti yang disarankan Bertrand. (ini adalah pilihan terbaik Anda jika Anda harus melakukan hal yang sama berulang kali)

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

{{foo | myFilter}}

Atau arahan khusus:

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>

Secara pribadi, dalam kebanyakan kasus saya akan pergi dengan fungsi pada lingkup saya, itu membuat markup cukup bersih, dan itu cepat dan mudah diimplementasikan. Kecuali, jika demikian, Anda akan melakukan hal yang persis sama berulang kali, dalam hal ini saya akan pergi dengan saran Bertrand dan membuat filter atau mungkin arahan, tergantung pada situasinya.

Seperti biasa, hal terpenting adalah solusi Anda mudah dipelihara , dan mudah-mudahan dapat diuji. Dan itu akan bergantung sepenuhnya pada situasi spesifik Anda.

Ben Lesh
sumber
18

Saya menggunakan yang berikut ini untuk menetapkan attr kelas secara kondisional ketika ng-class tidak dapat digunakan (misalnya saat menata SVG):

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

Pendekatan yang sama harus bekerja untuk tipe atribut lainnya.

(Saya pikir Anda harus menggunakan Angular terbaru yang tidak stabil untuk menggunakan ng-attr-, saya saat ini di 1.1.4)

Saya telah menerbitkan artikel tentang bekerja dengan AngularJS + SVG yang membahas tentang ini dan masalah terkait. http://www.codeproject.com/Articles/709340/Implementing-a-Flowchart-with-SVG-and-AngularJS

Ashley Davis
sumber
15

Untuk memeriksa konten variabel dan memiliki teks default, Anda dapat menggunakan:

<span>{{myVar || 'Text'}}</span>
Ezequielc
sumber
1
Terima kasih! Saya sudah mencoba ini tetapi saya melewatkan tanda kutip di sekitar string :-)
Simona Adriani
Untuk alasan apa pun, sintaks ini tidak berfungsi menggunakan binding satu kali .. {{:: myVar || 'Teks'}} tidak akan berfungsi. Harus tanpa ::
aoakes
3

Jika saya mengerti Anda dengan baik, saya pikir Anda memiliki dua cara untuk melakukannya.

Pertama, Anda bisa mencoba ngSwitch dan cara kedua yang mungkin adalah membuat filter Anda sendiri . Mungkin ngSwitch adalah pendekatan yang tepat tetapi jika Anda ingin menyembunyikan atau menampilkan konten sebaris hanya menggunakan filter {{}} adalah cara yang harus dilakukan.

Berikut ini biola dengan filter sederhana sebagai contoh.

<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';
}
Bertrand
sumber
3

Pustaka UI sudut memiliki built-in directive ui-if untuk kondisi dalam templat / Tampilan hingga angular ui 1.1.4

Contoh: Dukungan di UI Sudut hingga 1.1.1

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

ng-jika tersedia di semua versi sudut setelah 1.1.4

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

jika Anda memiliki data dalam variabel array maka hanya div yang akan muncul

JQuery Guru
sumber
ui-iftelah dihapus setidaknya dari versi terbaru angular-ui tetapi sejak angular 1.1.5 Anda miliki ng-if(dari komentar ini )
Dave Everitt
2

Jadi dengan Angular 1.5.1 (memiliki ketergantungan aplikasi yang ada pada beberapa dependensi tumpukan MEAN lain adalah mengapa saya saat ini tidak menggunakan 1.6.4)

Ini bekerja untuk saya seperti kata OP {{myVar === "two" ? "it's true" : "it's false"}}

{{vm.StateName === "AA" ? "ALL" : vm.StateName}}
Tom Stickel
sumber
2

jika Anda ingin menampilkan "Tidak Ada" ketika nilainya "0", Anda dapat menggunakan sebagai:

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

atau benar salah di sudut js

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

Bekerja bahkan dalam Situasi yang eksotis:

<br ng-show="myCondition == true" />
Steffomio
sumber
0

Saya akan melemparkan milik saya dalam campuran:

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

ini mengevaluasi pernyataan if sekali dan menambahkan no watch listener TETAPI Anda dapat menambahkan atribut tambahan ke elemen yang memiliki set-if disebut wait-for = "somedata.prop" dan itu akan menunggu data atau properti diatur sebelum mengevaluasi pernyataan if sekali. atribut tambahan itu bisa sangat berguna jika Anda sedang menunggu data dari permintaan 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');
              });
            }
          }
        };
      }
    };
  });
btm1
sumber