2015-01-24 17 views
12

Hãy tưởng tượng một số nội dung nặng có thể được hiển thị trên trang web, chẳng hạn như biểu đồ. Góc cung cấp 2 tùy chọn để chuyển đổi chế độ hiển thị của nội dung đã nói.Góc kết hợp ng-if và ng-show

ng-show sẽ hiển thị nội dung bất kể biểu thức và đơn giản "ẩn" sau khi thực tế. Đây không phải là lý tưởng vì người dùng có thể không bao giờ "mở" nội dung trong phiên của họ, do đó, nó là một sự lãng phí để làm cho nó.

ng-nếu tốt hơn trong lĩnh vực này. Sử dụng nó thay cho ng-show sẽ ngăn không cho nội dung nặng được hiển thị ở vị trí đầu tiên nếu biểu thức là sai. Tuy nhiên, sức mạnh của nó cũng là điểm yếu của nó, bởi vì nếu người dùng ẩn biểu đồ và sau đó hiển thị nó một lần nữa, nội dung được trả lại từ đầu mỗi lần.

Làm cách nào tôi có thể đưa ra chỉ thị tận dụng tối đa cả hai thế giới? Có nghĩa là nó hoạt động như ng-if cho đến khi nội dung được hiển thị lần đầu tiên, sau đó chuyển sang làm việc như ng-show để ngăn không cho hiển thị lại mỗi lần.

+1

ng-lười-show: http://developers.lendio.com/ blog/kết hợp-ng-if-và-ng-show-cho-tốt hơn-angularjs-hiệu suất/ – rinogo

+0

Cảm ơn, đó chính xác những gì tôi cuối cùng đã kết thúc bằng cách sử dụng tại thời điểm – parliament

Trả lời

18

1 về câu trả lời Denis, nhưng chỉ cho đầy đủ-sake, nó thậm chí có thể được đơn giản hóa hơn nữa bằng cách giữ logic trong Xem không có "ô nhiễm" bộ điều khiển:

<button ng-click="show = !show">toggle</button> 
<div ng-if="once = once || show" ng-show="show">Heavy content</div> 

plunker

EDIT: phiên bản ở trên có thể được cải thiện hơn nữa (và đơn giản) với một lần ràng buộc để giảm đồng hồ $ không cần thiết trên once - điều này sẽ chỉ hoạt động trong Angular 1.3+:

<div ng-if="::show || undefined" ng-show="show">Heavy content</div> 

Cần undefined để đảm bảo rằng giá trị được xem không "stabilize" trước khi nó trở thành true. Một khi nó ổn định, nó cũng mất đồng hồ $, do đó, nó sẽ không bị ảnh hưởng bởi bất kỳ thay đổi nào nữa để show.

+0

cập nhật mát mẻ, cảm ơn! – parliament

+0

Mẹo tuyệt vời, tôi sẽ nghĩ cách sử dụng lại nó, theo một cách nào đó! – fjcero

+0

Bí quyết tuyệt vời! Nhưng có cách nào để tái chỉ thị các chỉ thị khi cần thiết không? – kashesandr

9

Bạn có thể làm cho nó hoạt động bằng cách sử dụng ngIfngShow cùng nhau, trong đó mỗi bộ điều khiển theo biến khác nhau. ngIf sẽ được đặt thành true một lần và không bao giờ được đặt lại thành false một lần nữa, trong khi ngShow sẽ được chuyển đổi nhiều như người dùng muốn.

Hãy xem số fiddle này.

+0

hmmm touché sir – parliament

5

Đó là câu trả lời của @ new-dev đã truyền cảm hứng cho ý tưởng kết hợp của riêng tôi để có được một thành phần khá nặng bằng cách sử dụng nút bật tắt.

Vấn đề ban đầu của tôi là trang của tôi bao gồm ~ 20 thành phần mỗi lần tải ~ 1 giây để tải. Mỗi lần được bật lên bằng một nút.

Nếu sử dụng đồng bằng ng-nếu tôi sẽ tải trang tức thời và chậm trễ 1 giây sau khi nhấn chuyển đổi.

Nếu sử dụng đơn giản ng-show tôi sẽ nhận được máy ép chuyển đổi ngay lập tức nhưng 20 chậm trễ tải trang thứ hai ...

Vì vậy, bây giờ tôi kết hợp chúng với một điều khiển ng-mouseenter quá. Như thế này.

<div ng-mouseenter="create=true"> 
    <button ng-click="showAll = !showAll"></button> 
    <!--lightweight content--> 
    <div ng-show="showAll"> 
     <div ng-if="create"> 
      <!--Heavy content--> 
     </div> 
    </div> 
</div> 

Điều này đã cho tôi hiệu suất tuyệt vời trong cả Chrome và IE.Thời gian người dùng thực sự nhấp vào nút sau khi nhập thành phần được sử dụng để tạo DOM. Và sau đó các nút DOM được hiển thị nhanh chóng một lần (nếu) nhấp chuột đến.

Tôi cũng không bao giờ đặt biểu thức ng-if thành false nữa. Giữ DOM được lưu trong bộ nhớ cache nếu người dùng tiếp tục chuyển đổi phần đó.

Cập nhật: Lý do tôi không có ng-if và ng-show trên cùng một div là trong IE nó gây ra nhấp nháy. Khi sự kiện mouseenter đến, nó sẽ hiển thị nội dung và ẩn nó đi. Trong chrome nó là ok để có nó trên cùng một div.

+0

Hi thats trông tuyệt vời cho trường hợp của tôi. Tôi không thể sử dụng ng-mouseenter trên điện thoại hay tôi có thể? Phương án thay thế là gì. –

+0

Bạn nói đúng, Trên điện thoại hoặc máy tính bảng, nó không tạo ra bất kỳ hiệu suất tốc độ nào. Không chắc chắn nên sử dụng gì. – tkarls

0

Bạn có thể quan tâm đến chỉ thị tùy chỉnh ng-lazy-show bởi Alan Colver. Nó cho phép kết hợp cả hai ng-ifng-show:

<div ng-lazy-show="showFilters" lendio-business-filters></div> 

Mã này là nhỏ và có thể dễ dàng được thêm vào dự án của bạn:

var ngLazyShowDirective = ['$animate', function ($animate) { 

    return { 
    multiElement: true, 
    transclude: 'element', 
    priority: 600, 
    terminal: true, 
    restrict: 'A', 
    link: function ($scope, $element, $attr, $ctrl, $transclude) { 
     var loaded; 
     $scope.$watch($attr.ngLazyShow, function ngLazyShowWatchAction(value) { 
     if (loaded) { 
      $animate[value ? 'removeClass' : 'addClass']($element, 'ng-hide'); 
     } 
     else if (value) { 
      loaded = true; 
      $transclude(function (clone) { 
      clone[clone.length++] = document.createComment(' end ngLazyShow: ' + $attr.ngLazyShow + ' '); 
      $animate.enter(clone, $element.parent(), $element); 
      $element = clone; 
      }); 
     } 
     }); 
    } 
    }; 

}]; 

angular.module('yourModule').directive('ngLazyShow', ngLazyShowDirective); 
Các vấn đề liên quan