2017-09-22 45 views
5

पर अपडेट नहीं हो मैं अपने कोणीय आवेदन के लिए कोणीय 1.6.5 का उपयोग कर रहा है और एक बहुत ही अजीब व्यवहार देखा।कोणीय एनजी स्तरीय एनजी-व्यू

बात मैं हासिल करना चाहते हैं: जब ngroute बदला जा रहा है, मैं, वर्तमान दृश्य से सक्रिय वर्ग निकालना होगा पूरा करने के लिए है, तो नए दृश्य में सक्रिय वर्ग को जोड़ने छुट्टी एनीमेशन के लिए प्रतीक्षा करें।

मैं config में एप्लिकेशन और routs की स्थापना की है।

var app = angular.module('app', ['ngAnimate', 'ngRoute']); 

app.config(function ($routeProvider) { 
    $routeProvider 
     .when('/', { 
     templateUrl:"home.html", 
     reloadOnSearch:false 
     }) 
     .when('/about-us', { 
     templateUrl:"about.html", 
     reloadOnSearch:false 
     }) 
     .when('/contact', { 
     templateUrl:"contact.html", 
     reloadOnSearch:false 
     }) 
     .otherwise({ 
      template : "<h1>None</h1><p>Nothing has been selected</p>" 
     }); 
}); 

मैं एक सेवा है जहाँ मैं एनीमेशन के समय और देखने का बूलियन का संकेत दृश्यता की दुकान है:

app.service('animationProperties', function() { 
    this.animationTimings = { 
    views: 1000 
    }; 
    this.visibility = { 
    view : false 
    }; 
}); 

मैं सरल डिबगिंग समारोह और एक onRouteChangeStart समारोह के साथ एक मुख्य नियंत्रक है कि वर्तमान से सक्रिय वर्ग को दूर करना चाहिए (देखें दृश्यता बूलियन झूठे बनाकर) विचार:

app.controller('MainCtrl', function ($scope, $window, $location, 
            animationProperties) { 

    $scope.animationProperties = animationProperties; 

    $scope.$on('$routeChangeStart',function() { 
    animationProperties.visibility.view = false; 
    }); 

    $scope.toggleActive = function(){ 
    $scope.animationProperties.visibility.view = !$scope.animationProperties.visibility.view; 
    } 
}); 

और अंत में, ngAnimate छुट्टी एनीमेशन को पूरा करने के लिए इंतजार कर रहा है कि, तो (किया() विधि के साथ) वर्तमान दृश्य दूर करता है और दृश्यता बूलियन सच बनाकर फिर से नए दृश्य में प्रवेश करती है:

app.animation('.view', function($timeout, animationProperties) { 
    return { 
    enter: function(element, done) { 
     $timeout(function() { 
     animationProperties.visibility.view = true; 
     $timeout(function() { 
      done(); 
     }, animationProperties.animationTimings.views);//Wait to enter 
     },animationProperties.animationTimings.views); //Wait for leave function 
    }, 
    leave: function(element, done) { 
     $timeout(function() { 
     done(); 
     }, animationProperties.animationTimings.views); 
    } 
    } 
}); 

यहाँ plunker

है जब आप पृष्ठों स्विचन पहली बार (नेविगेशन से) आपको लगता है कि देखेंगे सबकुछ ठीक काम करता है, लेकिन पृष्ठों पर जाने पर दूसरी बार क्लास अपडेट नहीं हो रहा है, इसलिए एनीमेशन नहीं खेला जाता है। डिबगिंग करते समय आप स्पष्ट रूप से देख सकते हैं कि दृश्यता बूलियन सही ढंग से अपडेट किया गया है, लेकिन छोड़ने के दृश्य पर एनजी-क्लास अपडेट नहीं हो रहा है।

आपकी मदद की बहुत सराहना की जाएगी !!!

उत्तर

1

here से अपने आप का हवाला देते हुए:

  1. एक $routeChangeStart पर, आप मूल्य है कि (एक बार मूल्यांकन किया है) को बदलने ngClass बता छोड़ने से active वर्ग दूर करने के लिए होगा:

    यह क्या चल रहा है है राय।

  2. इसी समय, $route शुरू होता है उसका टेम्प्लेट हो रही सहित प्रवेश देखने के लिए, तैयार करने के लिए।
  3. एक बार सब कुछ तैयार है, यह $routeChangeSuccess घटना है, जो ngView संकेत दो दृश्य गमागमन शुरू करने के लिए चलाता है।
  4. अदला-बदली प्रक्रिया के दौरान, ngView छोड़ने देखने के दायरे, जो बाद से बात गुंजाइश की नजर बंद हो नष्ट कर देता है ... देखा था।

तो, अगर चरणों 1-4 पर्याप्त हो तेजी से, छोड़ने के दृश्य की गुंजाइश से पहले आवश्यक भाव ngClass लिए मूल्यांकन किया जाता active वर्ग दूर करने के लिए नष्ट हो जाता है। पहली बार जब आप किसी रूट पर जाते हैं, एनीमेशन काम करता है, क्योंकि $route को प्रवेश दृश्य के टेम्पलेट के लिए सर्वर अनुरोध करना है (जो ngClass अपना काम करने का समय देता है)। हालांकि, जब आप पहले गए मार्ग पर जाते हैं, तो टेम्पलेट पहले से ही कैश किया जाता है और संक्रमण तेज़ होता है।


आप जानबूझकर टेम्पलेट पुनर्प्राप्ति (यहां तक ​​कि एक वीएम बारी पर्याप्त है) धीमा इस पर काम कर सकते हैं। उदाहरण के लिए:

app.decorator('$templateRequest', ($delegate, $timeout) => { 
    const $templateRequest = (...args) => $delegate(...args). 
    then(tmpl => $timeout().then(() => tmpl)); 
    Object.defineProperty($templateRequest, 'totalPendingRequests', { 
    get:() => $delegate.totalPendingRequests, 
    set: nv => $delegate.totalPendingRequests = nv, 
    }); 
    return $templateRequest; 
}); 

(Updated plnkr 1)

उसके चारों ओर काम करने के लिए एक और तरीका है, अपने खुद के, साधारण, तुल्यकालिक ngClass के संस्करण को लागू करने के लिए इतना है कि कक्षाओं तुरंत, इससे पहले छोड़ने के दृश्य की गुंजाइश है ही लागू है है नष्ट किया हुआ। एक crud, इस तरह के एक निर्देश के unoptimized, गैर-उत्पादन के लिए तैयार संस्करण ऐसा दिखाई दे सकता:

app.directive('myClass',() => (scope, elem, attrs) => { 
    scope.$watchCollection(attrs.myClass, newValue => { 
    Object.keys(newValue).forEach(c => { 
     if (newValue[c]) { 
     elem.addClass(c); 
     } else { 
     elem.removeClass(c); 
     } 
    }); 
    }); 
}); 

(Updated plnkr 2)


सभी ही कहा जा रहा, तुम्हारा एक अजीब सेटअप की तरह लगता है:

  • किसी ईवेंट ($routeChangeStart) के लिए सुनो।
  • एक ध्वज सेट करें (animationProperties.visibility.views) जो कक्षा को हटाने के लिए ngClass को ट्रिगर करता है।
  • कक्षा को हटाने, एक सीएसएस एनीमेशन ट्रिगर करता है।
  • इस बीच, एक कस्टम जावास्क्रिप्ट एनीमेशन (animation('.view')) स्वयं को सीएसएस एनीमेशन के साथ सिंक्रनाइज़ करें और फिर ध्वज को वापस सेट करें।
  • ध्वज वापस सेट करके, प्रवेश दृश्य के लिए विपरीत सीएसएस एनीमेशन ट्रिगर करें।

शुरुआत के लिए, क्यों दोनों एक सीएसएस और एक जे एस एनीमेशन का उपयोग करें? उदाहरण के लिए आप जेएस एनीमेशन से अस्पष्टता परिवर्तन को संभालने में सक्षम हो सकते हैं (मान लें कि आपका वास्तविक सेटअप अधिक जटिल है और अन्य प्रभावों के लिए जेएस एनीमेशन की आवश्यकता है)।

या आप और अधिक आसानी से स्वचालित रूप से जोड़ के आधार पर एक शुद्ध सीएसएस एनीमेशन के साथ/बाहर में फीका संभाल कर सकते हैं/हटाया ng-enter/ng-leave वर्गों (यह सिर्फ 4 छोटे सीएसएस नियम है: स्माइली :):

[ng-view].ng-enter { 
    /* Wait for the leaving view to...leave, then start transitioning in. */ 
    transition: opacity 1s ease 1s; 
} 

[ng-view].ng-leave { 
    /* Start transitioning out. */ 
    transition: opacity 1s ease; 
} 

[ng-view].ng-enter, 
[ng-view].ng-leave.ng-leave-active { 
    /* 
    * At the beginning of the entering animation and 
    * at the end of the leaving animation, 
    * the view must be fully invisible. 
    */ 
    opacity: 0; 
} 

[ng-view].ng-enter.ng-enter-active, 
[ng-view].ng-leave { 
    /* 
    * At the end of the entering animation and 
    * at the beginning of the leaving animation, 
    * the view must be fully visible. 
    */ 
    opacity: 1; 
} 

(Updated plnkr 3)

संबंधित मुद्दे