เงื่อนไขแบบอินไลน์ใน angular.js


192

ฉันสงสัยว่ามีวิธีหนึ่งในการแสดงเนื้อหาแบบมีเงื่อนไขนอกเหนือจากการใช้ ng-show ฯลฯ ตัวอย่างเช่นใน backbone.js ฉันสามารถทำอะไรกับเนื้อหาแบบอินไลน์ในเทมเพลตเช่น:

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

แต่ในเชิงมุมฉันดูเหมือนจะถูก จำกัด ให้แสดงและซ่อนสิ่งต่าง ๆ ที่อยู่ในแท็ก html

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

อะไรคือวิธีที่แนะนำในเชิงมุมเพื่อแสดงและซ่อนเนื้อหาอินไลน์ในเชิงมุมโดยใช้เพียง {{}} แทนที่จะห่อเนื้อหาในแท็ก html


6
โปรดยอมรับคำตอบของฉันและยอมรับ 2Toad เมื่อคุณมีโอกาส
เบ็นเลช

คำตอบ:


139

แก้ไข: คำตอบของ 2 โหลดด้านล่างเป็นสิ่งที่คุณกำลังมองหา! โหวตขึ้นสิ่งนั้น

หากคุณใช้ Angular <= 1.1.4 คำตอบนี้จะทำ:

อีกหนึ่งคำตอบสำหรับเรื่องนี้ ฉันกำลังโพสต์คำตอบแยกต่างหากเพราะมันเป็นความพยายาม "แน่นอน" มากกว่าทางออกของรายการที่เป็นไปได้:

นี่คือตัวกรองที่จะทำ "ทันทีถ้า" (aka iif):

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

และสามารถใช้ดังนี้:

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

ขอบคุณ blesh นี่คือสิ่งที่ฉันจะทำ อย่างไรก็ตามฉันสังเกตเห็นว่าถ้าฉันพยายามใส่แท็ก html ในหนึ่งในค่าที่มันแบ่ง: {{thing.second == "two" | iif: "<ul class = 'two-class'>": "<ul>"}} ฉันรู้ว่าอาจมีวิธีที่ดีกว่าในการทำมุม แต่มีวิธีที่จะหลบหนี "<" และ ">" เพื่อให้แท็กสามารถส่งออกเป็นส่วนหนึ่งของสตริง?
user1469779

1
ngBind ไม่อนุญาตให้ใช้ HTML output คุณต้องการใช้ng-bind-html-unsafe
Ben Lesh

ตัวอย่างของ ng-binf-html-unsafe ในเอกสารเชิงมุมใช้ในแท็กตัวอย่างเช่น <ANY ng-bind-html-unsafe = "{expression}"> อาจเป็นไปไม่ได้ที่จะทำสิ่งที่ฉันพยายามทำแบบอินไลน์
user1469779

1
IIF เป็นตัวย่อของ "Inline If" เป็นเรื่องปกติในภาษาการเขียนโปรแกรมที่แตกต่างกัน ... ;)
เบ็นเลช

18
@BenLesh อุปกรณ์ประกอบฉากที่สำคัญสำหรับการแก้ไขคำตอบของคุณตอนนี้ว่ามีตัวเลือกอื่นทำงานได้ดี
Nick Coad

725

Angular 1.1.5เพิ่มการสนับสนุนสำหรับผู้ประกอบการที่ประกอบไปด้วย:

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

14
คำตอบที่มี upvotes มากที่สุดควรปรากฏที่ด้านบนของคำตอบ ... มันเป็นคำที่ถูกต้องที่สุด
Code Whisperer

3
user1469779 พิจารณาการยอมรับคำตอบนี้เป็นวิธีที่แนะนำในการบรรลุสิ่งที่คุณต้องการในช่วงเวลาหนึ่ง
Filip Kis

13
@ 2 โหลดคำตอบของฉันเก่า นี่คือคำตอบที่ถูกต้องตอนนี้ฉันไม่รู้ว่าผู้ใช้จะกลับไปที่ "ยอมรับ" ตอนนี้หรือไม่ แต่ฉันได้อธิบายคำตอบของฉันไว้ นั่นคือใบหน้าที่เปลี่ยนแปลงของการพัฒนาซอฟต์แวร์
เบ็นเลช

2
ขอบคุณ ฉันจะให้มันแสดงค่าของmyVarถ้ามันเป็นเท็จได้อย่างไร (เช่นฉันจะซ้อนตัวแปรในนิพจน์ได้อย่างไร) ฉันลองด้วย{{myVar === "two" ? "it's true" : {{myVar}}}}แต่ใช้ไม่ได้
Josh

6
@ Josh myVarคุณสมบัติไม่จำเป็นต้องห่อด้วยเครื่องหมายปีกกาเพิ่มเติมมันอยู่ในนิพจน์แล้ว ลอง{{myVar === "two" ? "it's true" : myVar}}
โหลด

60

แมวหลายพันวิธี ฉันรู้ว่าคุณกำลังถามเกี่ยวกับ {{}} ระหว่างกัน แต่สำหรับคนอื่นที่มาที่นี่ฉันคิดว่ามันคุ้มค่าที่จะแสดงตัวเลือกอื่น ๆ

ฟังก์ชันในขอบเขต $ ของคุณ(IMO นี่คือทางออกที่ดีที่สุดของคุณในสถานการณ์ส่วนใหญ่):

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

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

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

แน่นอน ng-show และ ng-hide แน่นอน:

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

ตัวกรองที่กำหนดเองตามที่แนะนำเบอร์แทรนด์ (นี่เป็นตัวเลือกที่ดีที่สุดของคุณหากคุณต้องทำสิ่งเดียวกันซ้ำแล้วซ้ำอีก)

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

{{foo | myFilter}}

หรือคำสั่งที่กำหนดเอง:

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>

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

และเช่นเคยสิ่งที่สำคัญที่สุดคือว่าการแก้ปัญหาของคุณเป็นเรื่องง่ายที่จะรักษาและเป็นทดสอบหวังว่า และนั่นจะขึ้นอยู่กับสถานการณ์ของคุณโดยเฉพาะ


18

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

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

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

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

ฉันได้ตีพิมพ์บทความเกี่ยวกับการทำงานกับ AngularJS + SVG ที่พูดถึงเรื่องนี้และปัญหาที่เกี่ยวข้อง http://www.codeproject.com/Articles/709340/Implementing-a-Flowchart-with-SVG-and-AngularJS


15

สำหรับการตรวจสอบเนื้อหาที่หลากหลายและมีข้อความเริ่มต้นคุณสามารถใช้:

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

1
ขอบคุณ! ฉันพยายามทำสิ่งนี้ แต่ฉันคิดถึงคำพูดรอบสตริง :-)
Simona Adriani

ไม่ว่าจะด้วยเหตุผลใดก็ตามไวยากรณ์นี้ใช้ไม่ได้กับการผูกครั้งเดียว .. {{:: myVar || 'ข้อความ'}} จะไม่ทำงาน จะต้องโดยไม่ต้อง :: เดอะ
aoakeson

3

ถ้าฉันเข้าใจคุณดีฉันคิดว่าคุณมีสองวิธีในการทำเช่นนั้น

แรกที่คุณอาจจะลองngSwitchและทางที่สองจะสร้างคุณเองกรอง อาจเป็น ngSwitch เป็น aproach ที่ถูกต้อง แต่ถ้าคุณต้องการซ่อนหรือแสดงเนื้อหาแบบอินไลน์โดยใช้ตัวกรอง {{}} เป็นวิธีที่จะไป

นี่คือซอที่มีตัวกรองอย่างง่ายเป็นตัวอย่าง

<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

Angular UI library มีคำสั่ง ui-if ในตัวสำหรับเงื่อนไขในเทมเพลต / มุมมองจนถึง UI ui 1.1.4

ตัวอย่าง: การสนับสนุนใน Angular UI ไม่เกิน ui 1.1.4

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

ng-if มีให้บริการในทุกรุ่นแองกูลาร์หลัง 1.1.4

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

หากคุณมีข้อมูลใด ๆ ในตัวแปรอาเรย์จะมีเพียง div เท่านั้นที่ปรากฏ


ui-ifถูกลบออกอย่างน้อยจากรุ่นล่าสุด angular-ui แต่เนื่องจาก angular 1.1.5 คุณมีng-if(จากความคิดเห็นนี้ )
Dave Everitt

2

ด้วย Angular 1.5.1 (มีการพึ่งพาแอปที่มีอยู่ในการพึ่งพา MEAN สแต็คอื่น ๆ บางส่วนคือเหตุผลที่ฉันไม่ได้ใช้ 1.6.4)

มันใช้งานได้สำหรับฉันเหมือนคำว่า OP {{myVar === "two" ? "it's true" : "it's false"}}

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

2

หากคุณต้องการแสดง "ไม่มี" เมื่อค่าเป็น "0" คุณสามารถใช้เป็น:

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

หรือเท็จจริงในเชิงมุม js

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


0

ฉันจะโยนระเบิดผสม:

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

สิ่งนี้จะประเมินว่าคำสั่ง if หนึ่งครั้งและเพิ่มไม่มีผู้ฟังการเฝ้าดู แต่คุณสามารถเพิ่มคุณสมบัติเพิ่มเติมให้กับองค์ประกอบที่มีการตั้งค่าถ้าเรียกว่ารอ -a = "somedata.prop" และมันจะรอข้อมูลหรือคุณสมบัตินั้นก่อน ประเมินคำสั่ง if เพียงครั้งเดียว แอตทริบิวต์เพิ่มเติมนั้นมีประโยชน์มากหากคุณกำลังรอข้อมูลจากคำขอ 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');
              });
            }
          }
        };
      }
    };
  });
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.