使两个布局共享相同的$ scope

时间:2017-02-19 16:07:13

标签: angularjs angularjs-scope angular-ui-router angularjs-routing angular-ui-router-extras

我想为我的内容提出两种布局(即horizontalvertical)。因此,切换选择器将自动导致相应的布局。这是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>

但是,使用上面的代码,每次我们更改视图时,$scope.one$scope.two都会重置为初始值。我希望无论布局如何变化,他们的文本区域都会发生变化。

有谁知道如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

我认为您应该使用nested视图 - 您可以在父路由状态上定义主控制器并定义与两个视图对应的两个嵌套状态。这种方式将保留父控制器(当切换子状态时不重新初始化)并且仅改变嵌套状态视图。像这样:

$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',
    ...
  })

答案 1 :(得分:0)

使用factoriesAngularJS factory documentation)轻松在不同视图之间共享相同数据。试试this example,它使用一个名为myFactory的简单工厂在控制器之间共享数据。这也适用于与您的情况相同的控制器。

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>