2015-11-28 20 views
8

Tôi là người dùng mới cho AngularJS và ui-router, và tôi đang cố gắng xoay đầu về cách quản lý phạm vi. Tôi đã mong đợi phạm vi của một bộ điều khiển hoạt động sẽ bị phá hủy khi nó trở thành không hoạt động trên sự thay đổi trạng thái, tuy nhiên, nó không xuất hiện như vậy.UI-Router - phạm vi không bị hủy khi thay đổi trạng thái?

Tôi đã sửa đổi ví dụ từ trang web của UI-Router để minh họa tình huống (xem plunker bên dưới). Mỗi khi trạng thái route1.list/route2.list được kích hoạt, chúng sẽ phát ra một sự kiện trên $ rootScope. Khi nhận được sự kiện, một câu lệnh gỡ lỗi sẽ được in ra bảng điều khiển.

Bằng cách chuyển đổi giữa hai trạng thái một vài lần, nó được quan sát thấy rằng tất cả các bộ điều khiển khởi tạo trước đây đã phản hồi sự kiện. Vì vậy, nó xuất hiện rằng các phạm vi được tạo ra bởi họ chưa bao giờ bị phá hủy. Hành vi này có được mong đợi không? Nếu vậy, tôi nên làm gì để chỉ các bộ điều khiển hoạt động mới trả lời một sự kiện?

Plunker

nhắn gỡ lỗi in trên Console: enter image description here

Code:

var myapp = angular.module('myapp', ["ui.router"]) 
myapp.config(function($stateProvider, $urlRouterProvider){ 

// For any unmatched url, send to /route1 
$urlRouterProvider.otherwise("/route1") 

đây là route1

$stateProvider 
    .state('route1', { 
     url: "/route1", 
     templateUrl: "route1.html" 
    }) 
    .state('route1.list', { 
     url: "/list", 
     templateUrl: "route1.list.html", 
     controller: function($rootScope, $scope){ 
      $rootScope.$emit("eventCT1"); 
      $rootScope.$on("eventCT2", fn); 
      function fn() { 
      console.log("Controller 1 receives an event emitted by Controller 2"); 
      } 
      $scope.items = ["A", "List", "Of", "Items"]; 
     } 
    }) 

và đây là tuyến đường 2

.state('route2', { 
     url: "/route2", 
     templateUrl: "route2.html" 
    }) 
    .state('route2.list', { 
     url: "/list", 
     templateUrl: "route2.list.html", 
     controller: function($rootScope, $scope){ 
      $rootScope.$emit("eventCT2"); 
      $rootScope.$on("eventCT1", fn); 
      function fn() { 
      console.log("Controller 2 receives an event emitted by Controller 1"); 
      } 
      $scope.things = ["A", "Set", "Of", "Things"]; 
     } 
    }) 
... 

Trả lời

4

Nếu chúng ta muốn làm điều gì đó với

1) $rootScope bên trong của bộ điều khiển (trong đó có tuổi thọ rất hạn chế),

2) chúng ta phải phá hủy đó, khi điều khiển (thực tế là $scope) đang bị phá hủy

Vì vậy, đây là cách móc và mở khóa

// get remove function 
var removeMe = $rootScope.$on("eventCT2", ...); 

// call that function 
$scope.$on("$destroy", removeMe) 

Nhưng, trong trường hợp trên, chúng tôi thậm chí không nên cố gắng

1) tạo ra một số hành động điều khiển cho một nhà nước ...

2) và hy vọng nó sẽ được gọi trong một điều khiển từ trạng thái khác nhau

những điều này sẽ không bao giờ sống chung với nhau

+0

Cảm ơn sự giúp đỡ của bạn. Có một điều tôi không hoàn toàn hiểu mặc dù - nếu bộ điều khiển trước đó bị phá hủy khi thay đổi trạng thái, không nên người nghe đã đăng ký với $ rootScope. $ On (tên, người nghe) trở thành không xác định?Tại sao nó vẫn được kích hoạt và không có lỗi nào bị ném? – CLDev

+0

Đó là "đóng cửa". Toàn bộ đối tượng, đại diện cho bộ điều khiển (và tất cả những gì tham chiếu) được lưu trong bộ nhớ ... để có thể phục vụ như người nghe. Đó là cách tốt nhất * cách tạo rò rỉ bộ nhớ. Tôi đề nghị, đọc về đóng cửa, và chủ yếu là làm ** KHÔNG ** sử dụng '$ rootScope' mà không hủy đăng ký ở cấp điều khiển. Hy vọng nó sẽ giúp một chút. Thưởng thức UI-Router và góc cạnh và bạn có thể né tránh câu trả lời nếu điều đó giúp bạn ... –

+1

Argh .. hiểu! Cảm ơn, câu trả lời được chấp nhận. – CLDev

-1

Nếu bạn đang sử dụng Ionic với kiễu góc, bạn có thể sử dụng life cycle events như vậy:

$scope.$on("$ionicView.beforeEnter", function(){ 
    //Do something every time this controller is the active scope. 
}) 

Bạn cũng có thể chơi xung quanh với các sự kiện khác được cung cấp trong liên kết ở trên. Và đó có thể là cách thực hành tốt nhất để giảm thiểu việc sử dụng $emit, điều này sẽ dẫn đến mã có thể đoán trước nhiều hơn và ít đột biến trạng thái hơn.

+0

Cảm ơn về sự giúp đỡ của bạn. Thật không may là dự án của tôi không sử dụng khung Ionic, và tôi không lường trước được nó. Vì vậy, tôi có lẽ phải khám phá các tùy chọn khác. – CLDev

Các vấn đề liên quan