ng-if hoặc ng-show phản hồi chậm (độ trễ 2 giây?)


87

Tôi đang cố gắng hiển thị hoặc ẩn chỉ báo đang tải trên một nút khi một yêu cầu bận. Tôi làm điều đó với angle bằng cách thay đổi biến $ scope.loading khi một yêu cầu đang tải hoặc khi tải xong.

 $scope.login = function(){
     $scope.loading = true;
    apiFactory.getToken()
        .success(function(data){

        })
        .error(function(error){

        })
         .finally(function(){
               $timeout(function() {
                 $scope.loading = false;
               }, 0);
         });
 };

Trong giao diện người dùng:

<button ng-disabled="loading" class="button button-outline button-positive" type="submit">
Log in 
<span ng-if="loading" class="ion-refreshing"></span>
</button>

Điều này hoạt động tốt, nhưng biểu tượng tải (làm mới ion) được hiển thị trong khoảng 2 giây, trong khi biến $ scope được cập nhật ngay lập tức. Tôi đã thử $ scope. $ Apply nhưng có vẻ không có gì sai ở đây, scope được cập nhật rất tốt và ngay sau khi có yêu cầu. Đó chỉ là biểu tượng không phản hồi đủ nhanh.

Cảm ơn đã giúp tôi hiểu điều này!


2
Bất kỳ hoạt ảnh liên quan?
tasseKATT

Tiêu cực. Không có hoạt ảnh liên quan. Sử dụng ng-class thay thế có vẻ hữu ích.
Jorre

Tôi đang gặp vấn đề tương tự hoặc tương tự. Phạm vi được cập nhật ngay lập tức và chính xác - Tôi đã xác minh điều này bằng cách ghi nhật ký thông báo từ các $scopechức năng ng-ifsử dụng để tìm hiểu xem các yếu tố liên quan có được hiển thị hay không. Tuy nhiên, các nút ng-ifvẫn hiển thị không chính xác hoặc bị ẩn trong một số giây. Sau đó, sau một thời gian ngắn, tất cả các nút chuyển sang trạng thái hiển thị / ẩn dự kiến ​​của chúng. - Tôi đã giải quyết vấn đề này bằng cách sử dụng ng-hidethay thế. Phiên bản Angular 1.2.16.
KajMagnus,

Bất kỳ giải pháp nào cho những người không sử dụng bất kỳ hình ảnh động nào?
Zia Ul Rehman Mughal

Câu trả lời:


124

Thử xóa ngAnimate nếu bạn không sử dụng nó khỏi cấu hình ứng dụng và trang index.html:

angular.module('myApp', [...'ngAnimate',...])

@Spock; nếu bạn vẫn yêu cầu sử dụng ngAnimate, hãy để nguyên cấu hình ứng dụng của bạn và chỉ cần thêm CSS sau:

.ng-hide.ng-hide-animate{
     display: none !important;
}

Điều đó sẽ ẩn biểu tượng động ngay sau khi điều kiện của bạn được đáp ứng.

Như bạn có thể thấy, chúng tôi đang đặt .ng-hide-animate thành ẩn. Đây là nguyên nhân gây ra sự chậm trễ khi chờ hoạt ảnh hoàn tất. Bạn có thể thêm hoạt ảnh vào sự kiện ẩn của mình như tên lớp của nó thay vì ẩn nó như trong ví dụ trên.


1
Tôi đã có một trang đơn giản với chỉ một vài ng-if, ng-showmà đang rất hài chậm. Tôi đã gỡ bỏ ngAnimatevà nó đã khắc phục sự cố cho tôi. Cảm ơn!
Eamonn Gahan

1
Điều này cũng giải quyết được vấn đề mà tôi đang gặp phải ... Bạn có biết tại sao sự hiện diện của ngAnimate lại gây ra quá trình chuyển đổi chậm không?
Clark

Có vấn đề tương tự - loại bỏ ngAnimate đã giải quyết được nó .. nhưng điều này không tốt .. nhiều mô-đun cần ngAnimate để làm các hình ảnh động thú vị .. phải làm gì? ngAnimattias bạn đang ở đâu? :)
Spock

21
Trong trường hợp ng-if, chỉ thêm .ng-leave { display:none; }vào phần tử đã là mẹo đối với tôi ( !importantkhông cần thiết).
Joao

40

Tôi đã gặp vấn đề tương tự và đã khắc phục nó bằng cách sử dụng ng-class với tên lớp 'hidden' để ẩn phần tử thay vì sử dụng ng-if hoặc ng-show / ng-hide.


1
Có vẻ liên quan đến hoạt ảnh và / hoặc trình xử lý sự kiện. Không thực sự chắc chắn lý do tại sao những người khác là chậm, nhưng tôi muốn biết
Thiago Festa

1
Làm thế nào bạn có thể làm điều này?
jsmedmar

Điều này nhanh hơn rất nhiều! Tại sao thế này ??
Aron

1
Tôi nghĩ điều này đơn giản là do việc sử dụng ngAnimate áp dụng các hành vi hoạt ảnh vào / ra cho các phần tử sử dụng ng-if / ng-show, trong khi nó không làm như vậy đối với các thay đổi trong biểu thức ng-class.
John Rix

@neimad làm thế nào điều này được thực hiện? Trong trường hợp của tôi, tôi cần sử dụng ng-if để kiểm tra xem một giá trị thuộc tính có phải là null( giá trị này trong vài giây chờ lệnh gọi api) hay không, vì vậy hai phần tử chọn sẽ hiển thị ngắn gọn. Vì vậy, bạn không sử dụng ng-if ở tất cả? Cảm ơn.
Chris

15

Tôi đã tìm thấy một số giải pháp ở đây , nhưng tốt nhất đối với tôi là ghi đè kiểu cho lớp .ng-animate:

.ng-animate.no-animate {
    transition: 0s none;
    -webkit-transition: 0s none;
    animation: 0s none;
    -webkit-animation: 0s none;
}

Trong html:

<button ng-disabled="loading" class="button button-outline button-positive" type="submit">
    Log in 
    <span ng-if="loading" class="ion-refreshing no-animate"></span>
</button>

Đây là một ví dụ: http://jsfiddle.net/9krLr/27/

Tôi hy vọng sẽ giúp bạn.


10

Tôi đang gặp phải vấn đề tương tự, tôi đã từng $scope.$evalAsync()buộc cập nhật ràng buộc.

Nó hoạt động như một say mê.

Tránh sử dụng $scope.$applyvì nó có thể xung đột với giai đoạn thông báo $ đã chạy.

if(selectedStatistics.length === 0 || selectedWorkgroups.length === 0){
    ctrl.isSaveDisabled = true;
    $scope.$evalAsync();
} else{
    ctrl.isSaveDisabled = false;
    $scope.$evalAsync();
}

Đã làm cho tôi. Nhưng nó có nhược điểm gì không?
Sarah Tammam,

1
Tôi đã không gặp phải bất kỳ. Nó rất tiện dụng trong trường hợp hoạt động không đồng bộ.
rach8garg

1
Cảm ơn bạn đã trả lời hữu ích :)
Sarah Tammam

Câu trả lời này dường như là một giải độc đắc, cảm ơn.
Abdeali Chandanwala

Nhân tiện, vấn đề bị trì hoãn này chủ yếu xảy ra trong môi trường localhost và hiếm khi được sản xuất - không biết tại sao
Abdeali Chandanwala

1

Tôi đã gặp vấn đề tương tự khi sử dụng

<div *ngIf='shouldShow'>
    <!-- Rest of DIV content here -->
</div>

Trong trường hợp của tôi, tôi đã giải quyết nó bằng cách thêm một lớp:

.hidden {
  display: none;
}

và sau đó thêm lớp có điều kiện thay vì sử dụng *ngIf:

<div [ngClass]="{'hidden': !shouldShow}">
    <!-- Rest of DIV content here -->
</div>

Nếu luôn sử dụng nó theo cách này, tôi sẽ xem xét đổi tên shouldShowthành shouldHide(và phủ định logic gán nó), vì vậy nó có thể được sử dụng shouldHidethay thế !shouldShow.

Nếu bạn có display: flextrong CSS của mình cho lớp hiện có của DIV, thuộc tính hiển thị đó có thể được ưu tiên hơn display: hidden. Có thể sử dụng một cách sửa chữa dễ dàng để display: none !importantthay thế, nhưng thường có những giải pháp tốt hơn để đảm bảo quyền ưu tiên theo những cách khác. Đây là một bài đọc tốt về các lựa chọn thay thế .


0

trong phiên bản góc 1.5.x thêm $scope.$apply()sau khi thay đổi điều kiện đã thực hiện công việc đối với tôi đây là một hàm ví dụ

$scope.addSample = function(PDF)
        {
            var validTypes ="application/pdf";
            if(PDF.type == validTypes)
            {
                //checking if the type is Pdf and only pdf
                $scope.samplePDF= PDF.files[0];
                $scope.validError = false;
                $scope.$apply();
            }

            else
            {
                 $scope.validError = true;
                 $scope.samplePDF= null;
                 $scope.$apply();
            }


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