Bir görünüm açıldığında / gösterildiğinde bir denetleyici işlevi çalıştırın


81

Altta üç iyon sekmesi bulunan klasik bir üç düğmeli menü kullanan açısal + iyonlu bir uygulama geliştiriyorum. Bir kullanıcı bir sekmeyi tıkladığında, bu şablon ui-yönlendirici aracılığıyla açılır.

Bunun gibi durumlar var:

$stateProvider
  .state('other', {
    url: "/other",
    abstract: true,
    templateUrl: "templates/other/other.html"
})

Şablonda şöyle bir şey yapıyorum:

<ion-nav-view name="other" ng-init="doSomething()"></ion-nav-view>

Denetleyicimde doSomething () işlevini yazabileceğimin ve onu orada elle çağırabileceğimin farkındayım. Yine de bu bana aynı sorunu veriyor. Biri bu görünümü açtığında, doSomething () işlevini birden çok kez nasıl çağıracağımı çözemiyorum.

Şu anda, doSomething () işlevi gayet iyi olarak adlandırılıyor, ancak yalnızca bu görünüm / sekme kullanıcı tarafından ilk açıldığında. Bir kullanıcı o görünümü veya sekmeyi her açtığında bir işlev çağırmak (coğrafi konumu güncellemek için) istiyorum.

Bunu uygulamanın doğru bir yolu ne olabilir?

Yardım ettiğin için teşekkürler!


{{doSomething ()}} deneyin?
Aşık

1
sorun doSomething () ile ilgili değil, çünkü bu gayet iyi çalışıyor, sadece iki kez tetiklenmeyecek. Görünüm ilk kez açıldığında sorunsuz çalışıyor, ikinci kez önbelleğe alınmış bir görünüm veya başka bir şey yükleniyormuş gibi görünüyor?
Jorre

ng-init işlevi yalnızca bir kez çağırır. kısmi görünümlerinizde ng-controller = "doSomething ()" veya {{doSomething ()}} çağırabilirsiniz ve yönlendirici / kısmi her çağrıldığında işlev çalıştırılır.
Asik

3
yapılandırma durumunuzda önbelleğinizi yanlış olarak ayarlayın. Cevabıma bak.
Yakob Ubaidi

Yanıtlar:


46

Görünümünüze belirli bir denetleyici atadıysanız, görünümünüz her yüklendiğinde denetleyiciniz çağrılır. Bu durumda, denetleyicinizde bazı kodları çalıştırılır çalıştırılmaz çalıştırabilirsiniz, örneğin şu şekilde:

<ion-nav-view ng-controller="indexController" name="other" ng-init="doSomething()"></ion-nav-view>

Ve kontrol cihazınızda:

app.controller('indexController', function($scope) {
    /*
        Write some code directly over here without any function,
        and it will be executed every time your view loads.
        Something like this:
    */
    $scope.xyz = 1;
});

Düzenleme: Durum değişikliklerini izlemeyi deneyebilir ve ardından rota değiştirildiğinde ve belirli bir rota ziyaret edildiğinde bazı kodlar çalıştırabilirsiniz, örneğin:

$rootScope.$on('$stateChangeSuccess', 
function(event, toState, toParams, fromState, fromParams){ ... })

Daha fazla ayrıntıyı burada bulabilirsiniz: Durum Değişikliği Olayları .


6
Teşekkürler, ama aynen bunu yapıyorum. Bu kod, görünüm ilk açıldığında yalnızca bir kez çalışacaktır. Konsoluma bir şey kaydetmeye çalıştım ve yalnızca ilk seferde tetikleniyor.
Jorre

Uygulamanızda çalıştığını söylediğinizde, bir iyonik uygulamadan da mı bahsediyorsunuz? Bunun benim için işe yaramadığını görmeye çalışıyorum.
Jorre

2
StateChange ile çalışmak işe yarıyor, sadece bir sekmeye tıklamak hala yalnızca bir kez çalışıyor. Düzenleme için teşekkürler!
Jorre

Bunun Ionic'in uygulamanızın belirli bölümlerini önbelleğe alma biçimiyle ilgisi olduğunu düşünüyorum. belki yanlışa ayarlamak cache-viewyardımcı olur? ionicframework.com/docs/api/directive/ionGörünüm önbellek görünümü
Michael Trouw

İonic'in son sürümüyle ilgili sorun belki de budur. Bununla birlikte, rotalar düzeyinde önbelleği de devre dışı bırakabilirsiniz. rotalar yapılandırmanızdaki her bir rotaya bir önbellek eklemeniz yeterlidir: false.
Manish Kr. Shukla

88

Varsayılan olarak, denetleyicileriniz önbellekti ve bu nedenle denetleyiciniz yalnızca bir kez ateşlendi. Belirli bir denetleyici için önbelleğe almayı kapatmak için .config(..).state, ayarlamanız ve cacheseçeneği olarak ayarlamanız gerekir false. Örneğin :

  .state('myApp', {
    cache: false,
    url: "/form",
    views: {
      'menuContent': {
        templateUrl: "templates/form.html",
        controller: 'formCtrl'
      }
    }
  })

daha fazla okumak için lütfen http://ionicframework.com/docs/api/directive/ionNavView/ adresini ziyaret edin.


2
Çıkış denetleyicisi için çok kullanışlı
mrwaim

3
İonic'te önbelleğe almanın varsayılan olarak açılması gerçekten talihsiz bir durum. Görünüşe göre bu, varsayılan olarak eklemek yerine isteğe bağlı bir özellik olmalı.
oalbrecht

Sadece bir durumu yeniden yüklemem gerekti, bu yüzden kullandım: $state.go('app.statename', {}, {reload:true});( daha fazla bilgi , kaynak ).
Sjoerd Pottuit

1
Bu işe yarasa da, bunun için tam olarak doğru yol değil. Uygulamanızı yavaşlatacak - kullanıcı bu görünüme her geçtiğinde tüm denetleyici başlatma prosedüründen geçmek istemediğinizi varsayarsak, jczaplew'in cevabının daha iyi bir yaklaşım olduğunu düşünüyorum.
Chris Rae

Harika şeyler. Tüm uygulama genelinde önbelleğe almayı devre dışı bıraktım. Bu cevaba rastladığıma sevindim
Robert Ngetich

50

AlexMart'ın cevabını ve bağlantısını takip ederek , şöyle bir şey çalışır:

.controller('MyCtrl', function($scope) {
  $scope.$on('$ionicView.enter', function() {
     // Code you want executed every time view is opened
     console.log('Opened!')
  })
})

3
$ionicView.beforeEntermuhtemelen istediğin şeydir. "görünüm tamamen girdikten" sonra$ionicView.enter patlar . Kullandığınız, animasyonlu görünümü geçişler kullanıyorsanız yürütür önce geçişinizin başlar. Bu, kodunuzu geçiş sırasında çalıştırabileceğiniz anlamına gelir ve bu da muhtemelen uygulamanızda "daha hızlı" bir his uyandırır. $ionicView.beforeEnter
rinogo

Bence bu sadece en basit ve net cevap. @Rinogo yorumu ile ilgili olarak, sanırım her programcı, view / controller'da ne olursa olsun "enter" veya "beforeEnter" kullanıp kullanmayacağına karar verebilir. Burada anlaşılması gereken önemli şey, görüşünüze her girdiğinizde bir işlevi çağırmak için yaşam döngüsü olaylarını yönetebileceğinizdir.
jcarballo

12

Ben de aynı sorunla karşılaştım ve burada bu davranışın nedenini aynı sorunu olan herkese bırakıyorum.

LifeCycle'ı Görüntüle

Performansı artırmak için, Ionic'in görüntüleme öğelerini önbelleğe alma ve verileri kapsamını iyileştirme becerisini geliştirdik. Bir denetleyici başlatıldığında, uygulamanın ömrü boyunca devam edebilir; sadece gizlidir ve izleme döngüsünden çıkarılır. Kapsamı yeniden oluşturmadığımız için, izleme döngüsüne tekrar girerken dinlememiz gereken olaylar ekledik.

Tam açıklamayı ve $ ionicView olaylarını görmek için şu adrese gidin: http://ionicframework.com/blog/navigating-the-changes/


9

Neden önbelleği cache-view = "false" ile devre dışı bırakmıyorsunuz ?

Sizin görüşünüze göre bunu iyon navigasyon görünümüne şu şekilde ekleyin:

<ion-nav-view name="other" cache-view="false"></ion-nav-view>

Veya bulunduğunuz eyalette Sağlayıcı:

$stateProvider.state('other', {
   cache: false,
   url : '/other',
   templateUrl : 'templates/other/other.html'
})

Her ikisi de kontrol cihazınızın her zaman çağrılmasını sağlayacaktır.


Bunun performans yan etkileri olmayacak mı? Görünümün önbelleğe alındığını ve her seferinde tüm görünümün yeniden yüklenmediğini sanıyordum. Bu özelliği devre dışı bırakmak, tüm sayfanın tekrar yüklenmesine neden olmazken, biz sadece bir kod parçasının tekrar çalıştırılmasını istiyoruz?
Sindarus

Muhtemelen evet @Sindarus. Ancak gerekli olan birkaç durum var. Bana göre, görünümde çizim yapan bir eklentim var ve onu nasıl temizleyeceğimi çözemedim.
Diogo Medeiros

Bu benim durumum için mükemmel bir çözümdü, kullanıcıyı kapatıyordum ve sonra denetleyiciyi tekrar ziyaret ediyordum, önbelleğe almak istemiyorum ve her şeyin yeniden başlatılması gerekiyor. teşekkür ederim!
Firas Abd Alrahman

5

Örneğin @Michael Trouw'a,

denetleyicinizin içine bu kodu girin. bu, bu duruma her girildiğinde veya aktif olduğunda çalışacaktır, önbelleği devre dışı bırakma konusunda endişelenmenize gerek yoktur ve bu daha iyi bir yaklaşımdır.

.controller('exampleCtrl',function($scope){
$scope.$on('$ionicView.enter', function(){
        // Any thing you can think of
        alert("This function just ran away");   
    });
})

Bir görünüm gösterilmeden önce çalışan $ ionicView.beforeEnter -> gibi daha fazla esneklik örneğine sahip olabilirsiniz. Ve biraz daha fazlası var.


2

Ionic'in yukarıda bahsedilen görüntüleme öğelerini ve kapsam verilerini önbelleğe alma yeteneği göz önüne alındığında, bu, görünüm her yüklendiğinde denetleyiciyi çalıştırmak istiyorsanız, bunu yapmanın başka bir yolu olabilir. İonic tarafından kullanılan önbelleğe alma mekanizmasını aşağıdakileri yaparak genel olarak devre dışı bırakabilirsiniz:

$ionicConfigProvider.views.maxCache(0);

Aksi takdirde, benim için çalışmasını sağlama şeklim

$scope.$on("$ionicView.afterLeave", function () {
     $ionicHistory.clearCache();
}); 

Bu, her tekrar girdiğinizde denetleyiciyi yeniden çalıştırmak için görünümden çıkmadan önce önbelleği temizlemek içindir.


1

Muhtemelen aradığınız şey buydu:

Ionic, görünümlerinizi ve dolayısıyla denetleyicilerinizi varsayılan olarak önbelleğe alır (en fazla 10) http://ionicframework.com/docs/api/directive/ionView/

Denetleyicinizin bu iyonik olaylara dayanarak belirli şeyleri yapmasına izin vermek için bağlanabileceğiniz olaylar vardır. bir örnek için buraya bakın: http://ionicframework.com/blog/navigating-the-changes/


1
Sadece bir bağlantı paylaşmak yerine örnek kod gösterilerek geliştirilebilir
Lawrence Weru

Angular Js'de de buna benzer bir şey var mı?
Wang'l Pakhrin

@ Wang'lPakhrin varsayılan olarak, ana denetleyici işlevinizde bildirdiğiniz ve çalıştırdığınız herhangi bir kod, IIFE veya işlev, görünüm (ve dolayısıyla denetleyici) her yüklendiğinde çalıştırılacaktır. Uygulamanızın ömrü boyunca bir işlevi çalıştırmak gibi olaylara ihtiyacınız varsa, açısal-ui-yönlendirici yapışkan durumlarına ViewContentLoadingve ViewContentLoadedolaylarına göz
Michael Trouw

0

Kamera sekmesini seçer seçmez yerel kamerayı yüklemeye çalıştığım ionic ile benzer bir sorun yaşadım. Denetleyiciyi kamera sekmesi için iyon görünümü bileşenine (tabs.html'de) ayarlayarak ve ardından kameramı yükleyen $ kapsam yöntemini (addImage) çağırarak sorunu çözdüm.

Www / templates / tabs.html’de

  <ion-tab title="Camera" icon-off="ion-camera" icon-on="ion-camera" href="#/tab/chats" ng-controller="AddMediaCtrl" ng-click="addImage()">
    <ion-nav-view  name="tab-chats"></ion-nav-view>
  </ion-tab>

AddMediaCtrl'de tanımlanan addImage yöntemi, kullanıcı "Kamera" sekmesini her tıkladığında yerel kamerayı yükler. Bunun çalışması için açısal önbellekte hiçbir şeyi değiştirmem gerekmedi . Umarım bu yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.