보기가 열리거나 표시 될 때마다 컨트롤러 기능 실행


81

3 개의 이온 탭이있는 하단의 클래식 3 버튼 메뉴를 사용하는 angular + ionic으로 앱을 구축하고 있습니다. 사용자가 탭을 클릭하면 해당 템플릿이 ui-router를 통해 열립니다.

다음과 같은 상태가 있습니다.

$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 ()}} 시도 하시겠습니까?
Asik 2014

1
문제는 doSomething ()이 잘 시작되지 않고 두 번 트리거되지 않는다는 것입니다. 보기가 처음 열릴 때 제대로 실행되고 두 번째로 캐시 된보기를로드하는 것처럼 보입니까?
Jorre 2014

ng-init는 함수를 한 번만 호출합니다. 부분보기에서 ng-controller = "doSomething ()"또는 {{doSomething ()}}을 호출 할 수 있으며 라우터 / 부분이 호출 될 때마다 함수가 실행됩니다.
Asik 2014

3
구성 상태에서 캐시를 false로 설정하십시오. 내 대답을 확인하십시오.
Yakob Ubaidi

답변:


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 2014

앱에서 작동한다고 말할 때 이온 앱에 대해서도 이야기하고 있습니까? 나는 그것이 나를 위해 작동하지 않는 경우인지 확인하려고합니다.
Jorre

2
stateChange로 작업하는 것은 트릭을 수행합니다. 탭을 클릭하는 것만으로도 여전히 한 번만 실행됩니다. 편집 해 주셔서 감사합니다!
Jorre 2014

Ionic이 앱의 특정 부분을 캐시하는 방식과 관련이 있다고 생각합니다. cache-viewfalse로 설정 하면 도움이 될까요? ionicframework.com/docs/api/directive/ionView 캐시보기 검색
Michael Trouw

이것은 아마도 최근에 출시 된 ionic의 문제 일 것입니다. 그러나 경로 수준에서 캐시를 비활성화 할 수도 있습니다. 경로 구성의 모든 경로에 캐시를 추가하십시오.
Manish Kr. 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
ionic에서 캐싱이 기본적으로 켜져 있다는 것은 정말 유감입니다. 이것은 기본적으로 추가하는 대신 옵트 인 기능이어야합니다.
oalbrecht 2015 년

하나의 상태 만 다시로드하면되므로 $state.go('app.statename', {}, {reload:true});( more info , source )를 사용했습니다.
Sjoerd Pottuit

1
이것이 작동하는 동안 그것에 대해 정확히 올바른 방법은 아닙니다. 앱 속도가 느려질 것입니다. 사용자가 해당 뷰로 전환 할 때마다 전체 컨트롤러 초기화 절차를 거치고 싶지 않다고 가정하면 jczaplew의 대답이 더 좋은 접근 방식이라고 생각합니다.
Chris Rae

훌륭한 물건. 전체 앱에서 캐싱을 비활성화했습니다. 다행 나는이 대답을 가로 질러 온
로버트 Ngetich에게

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 실행 됩니다. 애니메이션보기 전환을 사용 하는 경우 전환이 시작 되기 전에 using이 실행 됩니다. 즉 , 전환하는 동안 코드를 실행할 수있어 앱에서 "빠른"느낌을받을 수 있습니다. $ionicView.beforeEnter
rinogo

나는 이것이 가장 간단하고 깨끗한 대답이라고 생각합니다. @rinogo 주석과 관련하여 각 프로그래머는 뷰 / 컨트롤러에서 일어나는 일에 따라 "enter"또는 "beforeEnter"를 사용할지 여부를 결정할 수 있다고 생각합니다. 여기서 이해해야 할 중요한 점은 뷰에 들어갈 때마다 함수를 호출하도록 라이프 사이클 이벤트를 처리 할 수 ​​있다는 것입니다.
jcarballo

12

나는 같은 문제에 직면했고, 여기서 나는 같은 문제를 가진 다른 모든 사람들 에게이 행동의 이유를 남깁니다.

LifeCycle보기

성능을 개선하기 위해 뷰 요소 및 범위 데이터를 캐시하는 Ionic의 기능을 개선했습니다. 컨트롤러가 초기화되면 앱 수명 내내 지속될 수 있습니다. 시계주기에서 숨겨지고 제거됩니다. 스코프를 재 구축하는 것이 아니기 때문에 다시 감시주기에 들어갈 때 수신해야하는 이벤트를 추가했습니다.

전체 설명 및 $ ionicView 이벤트를 보려면 http://ionicframework.com/blog/navigating-the-changes/ 로 이동하십시오.


9

cache-view = "false"로 뷰 캐시를 비활성화하지 않는 이유 입니까?

보기에서 다음과 같이 ion-nav-view에 추가하십시오.

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

또는 stateProvider에서 :

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

어느 쪽이든 컨트롤러가 항상 호출되도록합니다.


성능 부작용이 없습니까? 뷰가 캐시되어 매번 전체 뷰가 다시로드되지 않는다고 가정했습니다. 이 기능을 비활성화해도 전체 페이지가 다시로드되지는 않지만 코드 일부만 다시 실행되기를 원합니까?
Sindarus 2016-08-05

아마도 예 @Sindarus. 그러나 필요한 경우가 몇 가지 있습니다. 나에게는 뷰에 플러그인 그림이 있는데 청소 방법을 알 수 없었습니다.
Diogo Medeiros

이것은 제 경우에 완벽한 솔루션이었습니다. 사용자를 로그 아웃 한 다음 컨트롤러를 다시 방문하고 캐시를 원하지 않으며 모든 것을 다시 초기화해야합니다. 감사합니다!
Firas Abd Alrahman

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
예제 코드를 보여주는 대신에 단순히 링크를 공유함으로써 개선 될 수있다
로렌스 Weru

Angular Js에도 이와 같은 것이 있습니까?
Wang'l Pakhrin

기본적으로 @ Wang'lPakhrin, 기본 컨트롤러 함수 내에서 선언하고 실행하는 모든 코드, IIFE 또는 함수는 뷰 (및 컨트롤러)가로드 될 때마다 실행됩니다. 당신이 필요로하는 경우 이벤트는 응용 프로그램의 일생에 한 번 기능을 실행 각도-UI-라우터 끈적 끈적한 상태 체크 아웃 같은 ViewContentLoadingViewContentLoaded이벤트 :
마이클 Trouw을

0

카메라 탭을 선택하자마자 기본 카메라를로드하려고 할 때 ionic과 비슷한 문제가 발생했습니다. 컨트롤러를 카메라 탭의 ion-view 구성 요소 (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>

AddMediaCtrl에 정의 된 addImage 메서드는 사용자가 "카메라"탭을 클릭 할 때마다 기본 카메라를로드합니다. 이 작업을 위해 각도 캐시에서 아무것도 변경할 필요 가 없습니다 . 이게 도움이 되길 바란다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.