Chạy chức năng bộ điều khiển bất cứ khi nào một dạng xem được mở / hiển thị


81

Tôi đang xây dựng một ứng dụng với góc + ion sử dụng menu ba nút cổ điển ở dưới cùng với ba tab ion trong đó. Khi người dùng nhấp vào một tab, mẫu đó sẽ mở qua ui-router.

Tôi có các trạng thái như thế này:

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

Trong mẫu, tôi làm một cái gì đó như:

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

Tôi biết rằng tôi có thể viết hàm doSomething () trong bộ điều khiển của mình và chỉ cần gọi nó theo cách thủ công ở đó. Điều đó mang lại cho tôi cùng một vấn đề. Tôi dường như không thể tìm ra cách gọi hàm doSomething () nhiều lần, bất cứ khi nào ai đó mở chế độ xem đó.

Ngay bây giờ, hàm doSomething () được gọi tốt, nhưng chỉ lần đầu tiên người dùng mở chế độ xem / tab đó. Tôi muốn gọi một hàm (để cập nhật vị trí địa lý) bất cứ khi nào người dùng mở chế độ xem hoặc tab đó.

Một cách đúng đắn để thực hiện điều đó là gì?

Cảm ơn vì đã giúp đỡ!


thử {{doSomething ()}}?
Asik

1
vấn đề không phải với doSomething () vì nó khởi chạy rất tốt, chỉ là nó sẽ không kích hoạt hai lần. Lần đầu tiên chế độ xem mở ra, nó chạy tốt, lần thứ hai có vẻ như nó chỉ tải lên một chế độ xem được lưu trong bộ nhớ cache hay gì đó?
Jorre

ng-init chỉ gọi hàm một lần. bạn có thể gọi ng-controller = "doSomething ()" hoặc {{doSomething ()}} trong các chế độ xem một phần và hàm của bạn được kích hoạt bất cứ khi nào bộ định tuyến / một phần được gọi.
Asik

3
ở trạng thái cấu hình của bạn, hãy đặt bộ nhớ cache của bạn thành false. Kiểm tra câu trả lời của tôi.
Yakob Ubaidi,

Câu trả lời:


46

Nếu bạn đã gán một bộ điều khiển nhất định cho chế độ xem của mình, thì bộ điều khiển của bạn sẽ được gọi mỗi khi chế độ xem của bạn tải. Trong trường hợp đó, bạn có thể thực thi một số mã trong bộ điều khiển của mình ngay khi nó được gọi, ví dụ như theo cách này:

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

Và trong bộ điều khiển của bạn:

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

Chỉnh sửa: Bạn có thể cố gắng theo dõi các thay đổi trạng thái và sau đó thực thi một số mã khi tuyến đường được thay đổi và một tuyến đường nhất định được truy cập, ví dụ:

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

Bạn có thể tìm thêm thông tin chi tiết tại đây: Sự kiện Thay đổi Bang .


6
Cảm ơn, nhưng đó chính xác là những gì tôi đang làm. Mã này sẽ chỉ chạy một lần, lần đầu tiên chế độ xem được mở. Tôi đã cố gắng đăng nhập thứ gì đó vào bảng điều khiển của mình và nó chỉ kích hoạt lần đầu tiên.
Jorre

Khi bạn nói rằng nó hoạt động trong ứng dụng của bạn, bạn cũng đang nói về một ứng dụng ion? Tôi đang cố gắng xem nếu đó có thể là trường hợp nó không hoạt động với tôi.
Jorre

2
Làm việc với stateChange thực hiện thủ thuật, chỉ cần nhấp vào một tab vẫn chỉ chạy một lần. Cảm ơn vì đã chỉnh sửa!
Jorre

Tôi nghĩ điều này liên quan đến cách Ionic lưu vào bộ nhớ cache các phần nhất định trong ứng dụng của bạn. có thể thiết lập cache-viewthành false sẽ giúp ích? ionicframework.com/docs/api/directive/ionXem tìm kiếm cho chế độ xem bộ nhớ cache
Michael Trouw

Đây có lẽ là vấn đề với việc phát hành ionic gần đây. Tuy nhiên, bạn cũng có thể tắt bộ nhớ cache ở cấp độ tuyến đường. chỉ cần thêm một bộ đệm ẩn: false vào từng và mọi tuyến đường trong cấu hình các tuyến đường của bạn.
Manish Kr. Shukla

88

Theo mặc định, bộ điều khiển của bạn là bộ nhớ cache và đó là lý do tại sao bộ điều khiển của bạn chỉ kích hoạt một lần. Để tắt bộ nhớ đệm cho một bộ điều khiển nhất định, bạn phải sửa đổi .config(..).statevà đặt cachetùy chọn thành false. ví dụ :

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

để đọc thêm, vui lòng truy cập http://ionicframework.com/docs/api/directive/ionNavView/


2
Rất hữu ích cho một bộ điều khiển logout
mrwaim

3
Thật không may khi bộ nhớ đệm được bật theo mặc định trong ionic. Có vẻ như đây nên là một tính năng chọn tham gia thay vì thêm nó theo mặc định.
oalbrecht

Tôi chỉ cần tải lại một trạng thái nên tôi đã sử dụng: $state.go('app.statename', {}, {reload:true});( thông tin thêm , nguồn ).
Sjoerd Pottuit

1
Mặc dù điều này hoạt động nhưng nó không phải là cách chính xác để thực hiện nó. Nó sẽ làm chậm ứng dụng của bạn - giả sử bạn không muốn thực hiện toàn bộ quy trình init controller mỗi khi người dùng chuyển sang chế độ xem đó, tôi nghĩ câu trả lời của jczaplew là một cách tiếp cận tốt hơn.
Chris Rae

Công cụ tuyệt vời. Tôi đã tắt bộ nhớ đệm trên toàn bộ ứng dụng. Vui vì tôi đã xem qua câu trả lời này
Robert Ngetich

50

Theo dõi câu trả lời và liên kết từ AlexMart , một cái gì đó như thế này hoạt động:

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

3
$ionicView.beforeEntercó lẽ là những gì bạn muốn. $ionicView.enterkích hoạt sau khi "chế độ xem đã nhập hoàn toàn" . Nếu bạn đang sử dụng chuyển đổi chế độ xem động, hãy sử dụng các lần $ionicView.beforeEnterthực thi trước khi quá trình chuyển đổi của bạn bắt đầu. Điều này có nghĩa là bạn có thể đang chạy mã của mình trong quá trình chuyển đổi, điều này có thể dẫn đến cảm giác "nhanh hơn" trong ứng dụng của bạn.
rinogo

Tôi nghĩ đây chỉ là câu trả lời đơn giản nhất và rõ ràng. Về nhận xét @rinogo, tôi nghĩ rằng mỗi lập trình viên có thể quyết định sử dụng "enter" hoặc "beforeEnter", tùy theo bất kỳ điều gì xảy ra trong chế độ xem / bộ điều khiển. Điều quan trọng cần hiểu ở đây là bạn có thể xử lý các sự kiện trong vòng đời để gọi một hàm mỗi khi bạn vào chế độ xem của mình.
jcarballo

12

Tôi đã đối mặt với cùng một vấn đề và ở đây tôi để lại lý do của hành vi này cho những người khác có cùng vấn đề.

Xem vòng đời

Để cải thiện hiệu suất, chúng tôi đã cải thiện khả năng của Ionic để lưu vào bộ nhớ cache của các phần tử xem và dữ liệu phạm vi. Khi bộ điều khiển được khởi chạy, nó có thể tồn tại trong suốt vòng đời của ứng dụng; nó chỉ bị ẩn và bị xóa khỏi chu kỳ theo dõi. Vì chúng tôi không xây dựng lại phạm vi, chúng tôi đã thêm các sự kiện mà chúng tôi nên lắng nghe khi vào lại chu kỳ xem.

Để xem mô tả đầy đủ và các sự kiện $ ionicView, hãy truy cập: http://ionicframework.com/blog/navicting-the-changes/


9

Tại sao bạn không tắt bộ nhớ cache của chế độ xem bằng cache-view = "false" ?

Theo quan điểm của bạn, hãy thêm cái này vào chế độ xem ion-nav như thế:

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

Hoặc trong trạng thái của bạnProvider:

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

Một trong hai sẽ làm cho bộ điều khiển của bạn luôn được gọi.


Điều này sẽ không có tác dụng phụ về hiệu suất? Tôi cho rằng chế độ xem được lưu vào bộ nhớ cache để toàn bộ chế độ xem không được tải lại mỗi lần. Tắt tính năng này sẽ không khiến toàn bộ trang tải lại, trong khi chúng ta chỉ muốn một đoạn mã được thực thi lại?
Sindarus

Có lẽ, có @Sindarus. Nhưng có một vài trường hợp là cần thiết. Đối với tôi, tôi có một bản vẽ plugin trên khung nhìn và tôi không thể tìm ra cách làm sạch nó.
Diogo Medeiros

Đây là một giải pháp hoàn hảo cho trường hợp của tôi, tôi đã đăng xuất người dùng sau đó truy cập lại bộ điều khiển, tôi không muốn lưu vào bộ nhớ cache và mọi thứ nên được khởi tạo lại. cảm ơn bạn!
Firas Abd Alrahman

5

Ví dụ với @Michael Trouw,

bên trong bộ điều khiển của bạn đặt mã này. điều này sẽ chạy mọi lúc khi trạng thái này được nhập hoặc hoạt động, bạn không cần phải lo lắng về việc tắt bộ nhớ cache và đó là một cách tiếp cận tốt hơn.

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

Bạn có thể có thêm ví dụ về tính linh hoạt như $ ionicView.beforeEnter -> chạy trước khi một chế độ xem được hiển thị. Và còn một số nữa về nó.


2

Xem xét khả năng của Ionic để lưu vào bộ nhớ cache các phần tử và dữ liệu phạm vi được đề cập ở trên, đây có thể là một cách làm khác, nếu bạn muốn chạy bộ điều khiển mỗi khi chế độ xem được tải. Bạn có thể vô hiệu hóa toàn cầu cơ chế bộ nhớ đệm được sử dụng bởi ionic bằng cách:

$ionicConfigProvider.views.maxCache(0);

Mặt khác, cách tôi làm cho nó hoạt động với tôi

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

Điều này là để xóa bộ nhớ cache trước khi rời khỏi chế độ xem để chạy lại bộ điều khiển mỗi khi bạn vào lại.


1

Đây có thể là những gì bạn đang tìm kiếm:

Ionic lưu trữ các chế độ xem của bạn và do đó bộ điều khiển của bạn theo mặc định (tối đa là 10) http://ionicframework.com/docs/api/directive/ionView/

Có những sự kiện bạn có thể tham gia để cho phép bộ điều khiển của bạn thực hiện một số việc dựa trên các sự kiện ion đó. xem ví dụ ở đây: http://ionicframework.com/blog/navicting-the-changes/


1
Có thể được cải thiện bằng cách hiển thị mã ví dụ thay vì chỉ đơn giản là chia sẻ một liên kết
Lawrence Weru

Có bất cứ điều gì giống như thế này trên Angular Js không?
Wang'l Pakhrin

@ Wang'lPakhrin theo mặc định, mọi mã, IIFE hoặc hàm mà bạn khai báo và chạy bên trong chức năng bộ điều khiển chính của mình sẽ được thực thi mỗi khi chế độ xem (và do đó bộ điều khiển) được tải. Nếu bạn cần sự kiện thích thực hiện một chức năng một lần trong cuộc đời của ứng dụng của bạn, hãy kiểm tra trạng thái dính góc-ui-router và ViewContentLoadingViewContentLoadedsự kiện :)
Michael Trouw

0

Tôi đã gặp sự cố tương tự với ionic trong đó tôi đang cố gắng tải máy ảnh gốc ngay khi tôi chọn tab máy ảnh. Tôi đã giải quyết vấn đề bằng cách đặt bộ điều khiển thành thành phần ion-view cho tab máy ảnh (trong tabs.html), sau đó gọi phương thức $ scope tải máy ảnh của tôi (addImage).

Trong www / template / 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>

Phương thức addImage, được định nghĩa trong AddMediaCtrl tải máy ảnh gốc mỗi khi người dùng nhấp vào tab "Máy ảnh". Tôi không phải thay đổi bất cứ điều gì trong bộ nhớ cache góc để điều này hoạt động. Tôi hi vọng cái này giúp được.

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.