3

我有一個簡單的多視圖Angular應用程序,它實現了一個嚮導,所以每次用戶點擊「下一步」按鈕時,應用程序都會導航到下一個視圖,而「後退」按鈕。我有一個$routeProvider配置,將所有視圖綁定到同一個控制器。每個視圖表示與輸入字段巨大的形式的塊,和$routeProvider管理跨它們導航:重新調用控制器時丟失輸入數據

app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) { 
    $routeProvider.when('/salespoints', { 
     templateUrl: 'salespoints', 
     controller: 'main' 
    }) 
    .when('/users', { 
     templateUrl: 'users', 
     controller: 'main' 
    }) 
    .otherwise({ 
     templateUrl: 'partner', 
     controller: 'main' 
    }); 

    $locationProvider.hashPrefix(''); 
}]); 

的問題是,每次用戶點擊「下一個」或「返回」時,所述控制器被調用,所以所有在前面的步驟中所做的$scope變化只是丟失:

app.controller('main', ['$scope', function ($scope) { 
    console.log('controller invoked'); // appears each time a user presses "Next" or "Back", hence re-instantiation of $scope 
}]); 

的應用是足夠小,轉向$rootScope的情況下,所有其他方法失敗,但我只是想避免,作爲一個反模式。

$scope保持在最新狀態的最佳方法是什麼?所有更改都是從應用實例生命週期的最初階段開始的,並且不會在每次更改視圖時重新實例化它?

+2

如果你wan't一個容器級別 – gr3g

回答

4

使用服務來保存表單數據並將其注入到控制器中。

angular.module('app').factory('formService', function() { 
    var data = {}; 
    return { 
     data: data 
    }; 
}); 

angular.module('app').controller('ctrl', function(formService) { 
    this.formData = formService.data; 
}); 
+0

在這種特殊情況下,應使用一個服務,我應該如何抓住視圖切換事件,如果沒有明確聽它?如果這是唯一的方法,'ng-route'是沒有用的,導航邏輯變得太複雜了。 –

+0

你現在離開你的路線,你只需要改變控制器來從服務中取出formData的值。 –

+0

得到它完美的工作,感謝提示。 –

1

控制器每次你在你的模板的新ng-controller時間實例化。

服務實例化一次,在第一時間你需要它,因爲他們是

所以應該使用角度服務來存儲數據,尤其是多個控制器實例之間共享的數據(即使它與您的示例中的控制器定義相同)。

1

因此,根據the advice of @joao-leal,我將數據持久性移至新服務並通過$scope.$watch訂閱$scope更新。該整體解決方案將導致一個相當簡單的代碼塊:

app.factory('formPersistence', function() { 
    var data = {}; 

    var get = function() { 
     return data; 
    }; 

    var set = function (updated) { 
     data = updated; 
    } 

    var reset = function() { 
     data = {}; 
    } 

    return { 
     get: get, 
     set: set, 
     reset: reset 
    }; 
}); 

app.controller('main', ['$scope', 'formPersistence', function ($scope, formPersistence) { 
    $scope.data = formPersistence.get(); 

    $scope.$watch('data', function() {     
     formPersistence.set($scope.data); 
    }); 
}]);