Angularjs,在路线之间穿越范围

我遇到过一个表单超过几页的情况(可能不太理想,但事实就是如此)。我希望为整个表单设置一个范围,这样如果用户在两个步骤之间来回走动,就很容易记住状态。

所以我需要用非常伪的代码:

  1. 设定 $scope.val = <Some dynamic data>
  2. 单击链接并路由到新模板(可能使用相同的控制器)。
  3. $scope.val仍然应该是相同的值,因为它是在最后一页。

以某种方式为范围持久化数据是正确的方法吗,还是有其他方法?您甚至可以创建一个在路由之间具有持久作用域的控制器吗? 当然,除了将其保存在数据库中之外。

69227 次浏览

You need to use a service since a service will persist throughout your app's life.

Lets say you want to save data pertaining to a user

This is how you define the service :

app.factory("user",function(){
return {};
});

In your first controller:

app.controller( "RegistrationPage1Controller",function($scope,user){
$scope.user = user;
// and then set values on the object
$scope.user.firstname = "John";
$scope.user.secondname = "Smith";
});


app.controller( "RegistrationSecondPageController",function($scope,user){
$scope.user = user;
// and then set values on the object
$scope.user.address = "1, Mars";


});

The service will work, but a logical way to do it using only ordinary scopes and controllers is to set up your controllers and elements so that it reflects the structure of your model. In particular, you need a parent element and controller that establish a parent scope. The individual pages of the form should reside in a view that is a child to the parent. The parent scope persists even as the child view is updated.

I assume you're using ui-router so you can have nested named views. Then in pseudo-code:

<div ng-controller="WizardController">
<div name="stepView" ui-view/>
</div>

Then WizardController defines the scope variables that you want to preserve across the steps of the multi-page form (which I'm referring to as a "wizard"). Then your routes will update stepView only. Each step can have its own templates, controllers and scopes, but their scopes are lost from page to page. But the scopes in WizardController are preserved across all pages.

To update the WizardController scopes from the child controllers, you'll need to use syntax like $scope.$parent.myProp = 'value' or define a function setMyProp on WizardController for each scope variable. Otherwise, if you try to set the parent scope variables directly from the child controllers, you'll end up just creating a new scope variable on the child itself, shadowing the parent variable.

Kind of hard to explain and I apologize for the lack of a full example. Basically you want a parent controller that establishes a parent scope, which will be preserved across all pages of your form.

The data can be passed between controllers through two ways

  1. $rootScope
  2. Model

The sample below demonstrates the passing of values using the model

app.js

angular.module('testApp')
.controller('Controller', Controller)
.controller('ControllerTwo', ControllerTwo)
.factory('SharedService', SharedService);

SharedService.js

function SharedService($rootScope){


return{
objA: "value1",
objB: "value2"
}
}

//Modify the value in controller A

Controller.js

function Controller($scope, SharedService){


$scope.SharedService = SharedService;


$scope.SharedService.objA = "value1 modified";
}

//Access the value in controllertwo

ControllerTwo.js

function ControllerTwo($scope, SharedService){


$scope.SharedService = SharedService;


console.log("$scope.SharedService.objA"+$scope.SharedService.objA); // Prints "value1 modified"
}

Hope this helps.