Запускайте функцію контролера щоразу, коли відкривається / відображається подання


81

Я будую додаток з angular + ionic, який використовує класичне меню з трьома кнопками внизу з трьома іонними вкладками. Коли користувач натискає вкладку, цей шаблон відкривається через інтерфейс користувача.

У мене є такі стани:

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

У шаблоні я роблю щось на зразок:

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

Мені відомо, що я можу записати функцію doSomething () у свій контролер і просто викликати її вручну там. Це дає мені таку ж проблему, хоча. Я не можу зрозуміти, як викликати функцію doSomething () більше одного разу, коли хтось відкриває це представлення.

Зараз функція doSomething () викликається просто чудово, але лише перший раз, коли користувач відкриває подання / вкладку. Я хотів би викликати функцію (для оновлення геолокації) кожного разу, коли користувач відкриває цей вигляд або вкладку.

Що було б правильним способом реалізувати це?

Дякуємо за допомогу!


спробувати {{doSomething ()}}?
Асік

1
проблема не в doSomething (), оскільки це запускається просто чудово, просто він не спрацює двічі. Перший раз, коли подання відкривається, він працює нормально, другий раз здається, що це просто завантаження кешованого подання чи щось інше?
Jorre

ng-init викликає функцію лише один раз. Ви можете зателефонувати ng-controller = "doSomething ()" або {{doSomething ()}} у ваших часткових поданнях, і функція запускається, коли викликається маршрутизатор / частковий.
Асік

3
у стані конфігурації встановіть кеш на false. Перевірте мою відповідь.
Якоб Убайді

Відповіді:


46

Якщо ви призначили певний контролер своєму поданню, тоді ваш контролер буде викликатись кожного разу, коли ваш вид завантажується. У цьому випадку ви можете виконати певний код у своєму контролері, як тільки він буде викликаний, наприклад, таким чином:

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

А у вашому контролері:

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;
});

Редагувати: Ви можете спробувати відстежити зміни стану, а потім виконати деякий код, коли маршрут змінюється та відвідується певний маршрут, наприклад:

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

Більш детальну інформацію ви можете знайти тут: Події щодо зміни стану .


6
Дякую, але я саме цим займаюся. Цей код буде запущений лише один раз, перший раз відкриття подання. Я намагався щось записати на свою консоль, і це спрацьовує лише вперше.
Jorre

Коли ви говорите, що це працює у вашому додатку, ви також говорите про іонний додаток? Я намагаюся зрозуміти, чи це може бути так, це не працює для мене.
Jorre

2
Робота з stateChange робить трюк, просто клацання на вкладці все одно виконується лише один раз. Дякуємо за редагування!
Хорре

Я думаю, це пов’язано з тим, як Ionic кешує певні частини вашого додатка. може cache-view, допоможе встановлення значення false ionicframework.com/docs/api/directive/ionView пошук кеш-перегляду
Michael Trouw

Можливо, це питання нещодавнього випуску іонних. Однак ви також можете вимкнути кеш-пам'ять на рівні маршрутів. просто додайте кеш: false до кожного маршруту у конфігурації маршрутів.
Маніш Кр. Shukla

88

За замовчуванням ваші контролери були кешованими, і саме тому ваш контролер запускався лише один раз. Щоб вимкнути кешування для певного контролера, вам потрібно змінити свій .config(..).stateі встановити для cacheпараметра опцію false. наприклад:

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

для подальшого читання, будь ласка, відвідайте http://ionicframework.com/docs/api/directive/ionNavView/


2
Дуже корисно для контролера виходу
mrwaim

3
Дуже прикро, що кешування ввімкнено за замовчуванням в іонній. Здається, це має бути функцією, яку ви хочете дозволити, а не додавати її за замовчуванням.
oalbrecht

Мені потрібно було лише перезавантажити один стан, тому я використав: $state.go('app.statename', {}, {reload:true});( більше інформації , джерело ).
Sjoerd Pottuit

1
Хоча це працює, це не зовсім правильний спосіб зробити це. Це буде сповільнювати роботу вашого додатка - припускаючи, що ви не хочете проходити всю процедуру ініціювання контролера щоразу, коли користувач перемикається на такий вигляд, я думаю, що відповідь jczaplew - це більш приємний підхід.
Chris Rae

Чудові речі. Я вимкнув кешування в усьому додатку. Радий, що натрапив на цю відповідь
Роберт Нгетіч

50

Наслідуючи відповідь та посилання від AlexMart , щось подібне працює:

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

3
$ionicView.beforeEnterце, мабуть, те, що ви хочете. $ionicView.enterзагоряється після того, як «вид повністю ввійшов» . Якщо ви використовуєте анімовані переходи перегляду, використовуйте $ionicView.beforeEnterвиконавці перед початком переходу. Це означає, що ви можете запускати свій код під час переходу, що, ймовірно, призведе до "швидшого" відчуття у вашому додатку.
rinogo

Я думаю, що це просто найпростіша і чітка відповідь. Щодо коментаря @rinogo, я думаю, що кожен програміст може вирішити, чи використовувати "enter" або "beforeEnter", залежно від того, що відбувається в поданні / контролері. Тут важливо зрозуміти, що ви можете обробляти події життєвого циклу, щоб викликати функцію кожного разу, коли ви входите у свій погляд.
jcarballo

12

Я зіткнувся з тією ж проблемою, і тут я залишаю причину такої поведінки для всіх інших з тією ж проблемою.

Переглянути LifeCycle

З метою підвищення продуктивності ми покращили здатність Ionic кешувати елементи перегляду та дані області. Після ініціалізації контролера він може зберігатися протягом усього життя програми; його просто приховано та видалено з годинного циклу. Оскільки ми не відновлюємо сферу дії, ми додали події, до яких нам слід прислухатися, коли знову входимо в цикл перегляду.

Щоб переглянути повний опис та події $ ionicView, перейдіть за посиланням: http://ionicframework.com/blog/navigating-the-changes/


9

Чому б вам не вимкнути кеш подання за допомогою cache-view = "false" ?

На ваш погляд, додайте це до перегляду ion-nav таким чином:

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

Або у вашому державному постачальнику:

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

Кожен з них змусить ваш контролер викликати завжди.


Хіба це не має побічних ефектів щодо продуктивності? Я припускав, що подання кешоване, щоб кожен вигляд не перезавантажувався щоразу. Вимкнення цієї функції не призведе до того, що вся сторінка знову завантажиться, тоді як ми хочемо лише повторне виконання фрагмента коду?
Sindarus

Можливо, так @Sindarus. Але є кілька випадків, які необхідні. Для мене у мене є плагін, який малює на поданні, і я не міг зрозуміти, як його очистити.
Діого Медейрос

Це було ідеальне рішення для мого випадку, я виходив з користувача, а потім знову відвідував контролер, я не хочу кешувати, і все слід повторно ініціалізувати. Дякую!
Фірас Абд Алрахман

5

Наприклад, до @Michael Trouw,

всередині вашого контролера помістіть цей код. це буде працювати кожного разу, коли цей стан буде введено або активне, вам не потрібно турбуватися про вимкнення кешу, і це кращий підхід.

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

Ви можете навести більше прикладів гнучкості, таких як $ ionicView.beforeEnter ->, який запускається до відображення подання. І є ще дещо.


2

Беручи до уваги здатність Ionic кешувати елементи перегляду та дані обсягу, згадані вище, це може бути іншим способом, якщо ви хочете запускати контролер кожного разу, коли подання завантажується. Ви можете глобально вимкнути механізм кешування, який використовує ionic, виконавши:

$ionicConfigProvider.views.maxCache(0);

В іншому випадку, як я працював у мене це робило

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

Це потрібно для очищення кеш-пам’яті перед тим, як залишати подання для повторного запуску контролера кожного разу, коли ви повертаєтеся назад.


1

Це, мабуть, те, що ви шукали:

Ionic кешує ваші подання і, отже, ваші контролери за замовчуванням (макс. 10) http://ionicframework.com/docs/api/directive/ionView/

Є події, на які можна підключитись, щоб дозволити своєму контролеру робити певні дії на основі цих іонних подій. див. тут приклад: http://ionicframework.com/blog/navigating-the-changes/


1
Можна покращити, показавши приклад коду, а не просто поділившись посиланням
Лоуренс Веру

Чи є щось подібне і на Angular Js?
Вангл Пахрін,

@ Wang'lPakhrin за замовчуванням, будь-який код, IIFE або функція, які ви оголошуєте та запускаєте всередині вашої основної функції контролера, будуть виконуватися кожного разу, коли подання (і, отже, контролер) завантажується. Якщо вам потрібні такі події, як виконання функції один раз у житті вашої програми, перевірте липкі стани ViewContentLoadingта ViewContentLoadedподії
angular

0

У мене була подібна проблема з ionic, коли я намагався завантажити рідну камеру, як тільки вибрав вкладку камери. Я вирішив проблему, встановивши для контролера компонент іонного перегляду для вкладки камери (у tabs.html), а потім викликав метод $ scope, який завантажує мою камеру (addImage).

У www / templates / tabs.html

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

Метод addImage, визначений у AddMediaCtrl, завантажує власну камеру щоразу, коли користувач натискає вкладку "Камера". Мені не потрібно було нічого змінювати в кутовому кеші, щоб це працювало. Сподіваюся, це допоможе.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.