2015-05-07 20 views
16

Có một thẳng về phía trước, cách đơn giản để làm như sau -có điều kiện thêm thuộc tính chỉ thị góc tới một yếu tố

<div class="my-class" my-custom-directive="{{evaluate expression}}"></div> 

Vì vậy mà góc sẽ không thêm chỉ thị trừ khi biểu thức được đánh giá là true ?

Edit:

Chỉ thị phải là một thuộc tính vì vậy hãy, không có các giải pháp như ng-if với restrict: 'E',
ng-class với restrict: 'C' hoặc ng-attr - mà không làm việc với các chỉ thị tùy chỉnh.

Trả lời

4

Có thể thực hiện việc này bằng cách tạo chỉ thị có mức độ ưu tiên cao và terminal: true. Sau đó, bạn có thể fiddle với các thuộc tính phần tử (thêm hoặc loại bỏ chúng) và sau đó biên dịch lại phần tử để cho các chỉ thị chạy.

Dưới đây là ví dụ như một nặng nề: http://plnkr.co/edit/DemVGr?p=info

Thay đổi biểu hiện trong "chỉ thị nếu" thuộc tính để giữ/xóa các "logger" chỉ thị.

Nếu biểu thức cho thuộc tính đánh giá là false thì biểu thức đó sẽ bị xóa.

<div directive-if="{'logger': 'myValue == 1'}" 
    logger="testValue"> 
    <p>"logger" directive exists? <strong>{{logger}}</strong></p> 
</div> 

Đây là triển khai chỉ thị.

Với một số chỉnh sửa nhỏ, bạn có thể trao đổi điều này xung quanh thành phố thêm chỉ thị thay vì xóa chúng nếu đó là những gì bạn muốn.

/** 
* The "directiveIf" directive allows other directives 
* to be dynamically removed from this element. 
* 
* Any number of directives can be controlled with the object 
* passed in the "directive-if" attribute on this element: 
* 
* {'attributeName': 'expression'[, 'attribute': 'expression']} 
* 
* If `expression` evaluates to `false` then `attributeName` 
* will be removed from this element. 
* 
* Usage: 
* 
*   <any directive-if="{'myDirective': 'expression'}" 
*     my-directive> 
*   </any> 
* 
*/ 
directive('directiveIf', ['$compile', function($compile) { 

    // Error handling. 
    var compileGuard = 0; 
    // End of error handling. 

    return { 

     // Set a high priority so we run before other directives. 
     priority: 100, 
     // Set terminal to true to stop other directives from running. 
     terminal: true, 

     compile: function() { 
      return { 
       pre: function(scope, element, attr) { 

        // Error handling. 
        // 
        // Make sure we don't go into an infinite 
        // compile loop if something goes wrong. 
        compileGuard++; 
        if (compileGuard >= 10) { 
         console.log('directiveIf: infinite compile loop!'); 
         return; 
        } 
        // End of error handling. 


        // Get the set of directives to apply. 
        var directives = scope.$eval(attr.directiveIf); 
        angular.forEach(directives, function(expr, directive) { 
         // Evaluate each directive expression and remove 
         // the directive attribute if the expression evaluates 
         // to `false`. 
         var result = scope.$eval(expr); 
         if (result === false) { 
          // Set the attribute to `null` to remove the attribute. 
          // 
          // See: https://docs.angularjs.org/api/ng/type/$compile.directive.Attributes#$set 
          attr.$set('logger', null) 
         } 
        }); 


        // Remove our own directive before compiling 
        // to avoid infinite compile loops. 
        attr.$set('directiveIf', null); 

        // Recompile the element so the remaining directives 
        // can be invoked. 
        var result = $compile(element)(scope); 


        // Error handling. 
        // 
        // Reset the compileGuard after compilation 
        // (otherwise we can't use this directive multiple times). 
        // 
        // It should be safe to reset here because we will 
        // only reach this code *after* the `$compile()` 
        // call above has returned. 
        compileGuard = 0; 

       } 
      }; 

     } 
    }; 
}]); 
+0

Phản ánh về điều này, nếu bạn định cấu hình chỉ thị có giá trị biểu thức thay cho các chuỗi như thế này 'directive-if =" {'logger': myValue == 1} "' (lưu ý rằng 'myValue == 1' là một biểu thức và không phải là một chuỗi có) sau đó bạn không cần 'phạm vi' $ eval (expr) 'bên trong vòng lặp. –

2

@Sly_cardinal là đúng, sử dụng mã của mình, nhưng phải thực hiện một vài điều chỉnh:

(function() { 

angular.module('MyModule').directive('directiveIf', function ($compile) { 

    // Error handling. 
    var compileGuard = 0; 
    // End of error handling. 

    return { 

     // Set a high priority so we run before other directives. 
     priority: 100, 
     // Set terminal to true to stop other directives from running. 
     terminal: true, 

     compile: function() { 
      return { 
       pre: function(scope, element, attr) { 

        // Error handling. 
        // Make sure we don't go into an infinite 
        // compile loop if something goes wrong. 
        compileGuard++; 
        if (compileGuard >= 10) { 
         console.log('directiveIf: infinite compile loop!'); 
         return; 
        } 


        // Get the set of directives to apply. 
        var directives = scope.$eval(attr.directiveIf); 

        for (var key in directives) { 
         if (directives.hasOwnProperty(key)) { 

          // if the direcitve expression is truthy 
          if (directives[key]) { 
           attr.$set(key, true); 
          } else { 
           attr.$set(key, null); 
          } 
         } 
        } 

        // Remove our own directive before compiling 
        // to avoid infinite compile loops. 
        attr.$set('directiveIf', null); 

        // Recompile the element so the remaining directives 
        // can be invoked. 
        var result = $compile(element)(scope); 


        // Error handling. 
        // 
        // Reset the compileGuard after compilation 
        // (otherwise we can't use this directive multiple times). 
        // 
        // It should be safe to reset here because we will 
        // only reach this code *after* the `$compile()` 
        // call above has returned. 
        compileGuard = 0; 

       } 
      }; 

     } 
    }; 
}); 

})(); 
+0

Cảm ơn, Mặc dù mã này có thể hoạt động (không biết, không kiểm tra), tôi hầu như không gọi đó là "đơn giản" hoặc "đơn giản". Nó trông rất nguy hiểm và dễ bị lỗi (Chỉ cần nhìn vào số lượng của 'Errror handlind' ý kiến) và tôi không chuyên gia góc đủ để biết những hậu quả nó sẽ có trên ứng dụng của tôi .. – Daniel

0

cách tiếp cận khác là tạo ra hai phiên bản của mã - một khi chỉ là cần thiết và một số khác khi không phải vậy. Và hiển thị bằng cách sử dụng ng-if/ng-show một hay khác. Mã trùng lặp có thể được di chuyển đến các mẫu và chúng có thể được bao gồm.

Các vấn đề liên quan