I want to propose two layouts (ie, horizontal
and vertical
) for my contents. So switching in the selector will lead automatically to the corresponding layout. Here is the JSBin :
<html ng-app="flapperNews">
<head>
<script src="https://code.jquery.com/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.2/angular-ui-router.js"></script>
<script type="text/ng-template" id="horizontal.tpl">
<textarea ng-model="one"></textarea>, <textarea ng-model="two"></textarea>
<br><br>{{one}}+{{two}}
</script>
<script type="text/ng-template" id="vertical.tpl">
<textarea ng-model="one"></textarea><br><textarea ng-model="two"></textarea>
<br><br>{{one}}+{{two}}
</script>
<script>
var app = angular.module('flapperNews', ['ui.router']);
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('entry', {
url: '/',
params: { tpl: 'vertical' },
templateUrl: function (params) {
return params.tpl + ".tpl"
}
})
}]);
app.controller('MainCtrl', ['$scope', '$state', function ($scope, $state) {
$scope.one = "one";
$scope.two = "two";
$scope.layouts = ["horizontal", "vertical"];
$scope.$watch('layout', function () {
$state.go('entry', {tpl: $scope.layout});
})
}])
</script>
</head>
<body ng-controller="MainCtrl">
<select ng-model="layout" ng-init="layout = 'horizontal' || layouts[0].value" ng-options="x for x in layouts"></select>
<br><br>
<ui-view></ui-view>
</body>
</html>
However, with the above code, each time we change the view, $scope.one
and $scope.two
are reset to their initial values. I would hope the change in their textarea would remain regardless of the change of layout.
Does anyone know how to solve this?
I think that you should use nested views - you can define main controller on parent route state and define two nested states corresponding to two views. This way parent controller will remain (it's not re-initialised when child states are switched) and only nested states views will be changed. Something like this:
$stateProvider
.state('myState', {
url: '/test/',
template: '<div ui-view></div>',
controller: function() {
//main controller shared by child states
...
}
})
.state('myState.view1', {
url: '/test/view1'
templateUrl: 'tpl-1.hmtl',
...
})
.state('myState.view2', {
url: '/test/view2'
templateUrl: 'tpl-2.hmtl',
...
})
Easy sharing same data between different views by using factories
( AngularJS factory documentation ). Try this example , it uses a simple factory named myFactory
to share data between controllers. This also does work on the same controller as in your case.
var myApp = angular.module("myApp",[ "ui.router"]); myApp.config(function ($stateProvider, $urlRouterProvider){ $stateProvider.state("state1", { url: "#", template: '<p>{{ aValue }}</p><button ng-click="bindValue(\\'its me\\')">Bind value</button>', controller: "myController" }).state("state2", { url: "#", template: '<p>{{ aValue }}</p><button ng-click="bindValue(\\'its me\\')">Bind value</button>', controller: "myController" }); }); myApp.controller( "myController", function($scope, myFactory) { $scope.aValue = myFactory.myValue; $scope.bindValue = function (value) { $scope.aValue = value; myFactory.myValue = value; } }); myApp.factory('myFactory', function () { return { myValue: '' } });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script> <div ng-app="myApp"> <nav> <a ui-sref="state1">State 1</a> <a ui-sref="state2">State 2</a> </nav> <div ui-view></div> </div>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.