Two views in one AngularUI Router state sharing scope

前端 未结 2 1353
野的像风
野的像风 2020-12-03 08:01

I am pretty new to the AngularUI Router and would like the use it for the following scenario:

The layout common to all pages includes a top navbar c

相关标签:
2条回答
  • 2020-12-03 08:28

    $scope is not the model, its a reference to a model, glue in between the data & the view. If $scopes in two, or more, controllers need to share one model/state/data use a singleton object instance by registering a angular service. That one service/factory can be injected into as many controllers as you like, and then everything can work off that one source of truth.

    Heres a demo of 1 factory linking $scopes in navbar & body with ui-router http://plnkr.co/edit/P2UudS?p=preview (left tab only)

    ui-router (viewC is navbar):

    $stateProvider
    .state('left', {
      url: "/",
      views: {
        "viewA": {
          controller: 'LeftTabACtrl',
          template: 'Left Tab, index.viewA <br>' +
                    '<input type="checkbox" ng-model="selected2.data" />' +
                    '<pre>selected2.data: {{selected2.data}}</pre>'
        },
        {...},
        "viewC": {
          controller: 'NavbarCtrl',
          template: '<span>Left Tab, index.viewC <div ui-view="viewC.list"></div>' +
                    '<input type="checkbox" ng-model="selected.data" />' +
                    '<pre>selected.data: {{selected.data}}</pre></span>'
        }
      }
    })
    

    Factory & Controllers:

    app.factory('uiFieldState', function () {
        return {uiObject: {data: null}}
    });
    
    app.controller('NavbarCtrl', ['$scope', 'uiFieldState', '$stateParams', '$state',
        function($scope, uiFieldState, $stateParams, $state) {
            $scope.selected = uiFieldState.uiObject;
        }
    ]);
    
    app.controller('LeftTabACtrl', ['$scope', 'uiFieldState', '$stateParams', '$state',
        function($scope, uiFieldState, $stateParams, $state) {
            $scope.selected2 = uiFieldState.uiObject;
        }
    ]);
    

    As you can see, the factory object {uiObject: {data: null}} is injected into the controller with uiFieldState & then its simply $scope.selected = uiFieldState.uiObject; for connecting the factory to the scope ng-model="selected.data" .`

    0 讨论(0)
  • 2020-12-03 08:41

    You should use:

    $on and $emit
    

    The emit controller, that sends the data.

    angular.module('MyApp').controller('MyController', ['$scope', '$rootScope', function ($scope, $rootScope){
    
      $rootScope.$emit('SomeEvent', data);
    }]);
    

    An example of how to implement $rootScope a safe way so it destroys and fixes stuff after use:

    angular
    .module('MyApp')
    .config(['$provide', function($provide){
        $provide.decorator('$rootScope', ['$delegate', function($delegate){
    
            Object.defineProperty($delegate.constructor.prototype, '$onRootScope', {
                value: function(name, listener){
                    var unsubscribe = $delegate.$on(name, listener);
                    this.$on('$destroy', unsubscribe);
                },
                enumerable: false
            });
    
    
            return $delegate;
        }]);
    }]);
    

    And the controller with the data that should be treated.

    angular.module('MyApp')
    .controller('MySecondController', ['$scope', function MyController($scope) {
    
            $scope.$onRootScope('SomeEvent', function(event, data){
                console.log(data);
            });
        }
    ]);
    

    You could pass in $rootScope instead of using the $scopes method $onRootScope that we defined in the config. However, this is not a recommended way of using $emit and $onRootScope.

    Instead of using $emit, you could always use $broadcast. This would however give you very huge performance issues as your app grows. Since it bubbles the data through all controllers.

    If your controllers are parents and child to each other, they don't have to use the $rootScope.

    Here is and example of the difference between $emit and $broadcast: jsFiddle

    And their is really performance differences:

    enter image description here

    0 讨论(0)
提交回复
热议问题