Pragma Dev
Pragma Dev

Reputation: 65

Angular UI Router - Access $scope outside ui view

I want to access $scope outside my UI view. My app structure is simple. It is a todo app having three panels like this My todo app design

Here is the full code https://github.com/udayghulaxe/ticitic_todo

What I want is, I want to access to do detail on the third panel, and I have to do it using $rootScope which is not a proper way to send data, I have assign separate controllers to each three panels. I am changing the state of UI router on click of the to do. I just want to access to do data in the third panel

<!-- Routers -->

.state('dashboard', {
  url: '/dashboard',
  abstract: true,
  views: {
    '': {
      templateUrl: './partials/main.html'
    },
    'header_toolbar@dashboard': {
      templateUrl: './views/header_toolbar.html'
    },
    'sidenavleft@dashboard': {
      templateUrl: './views/sidenav.html'
    },
 
    'todo_detail@dashboard': {
      templateUrl: './views/todo_detail.html'
    }

  }
})

.state('dashboard.listdetail', {
  url: '/lists/:list_id/',
  templateUrl: './partials/list.detail.html',
  controller: 'ListController',
  resolve: {
    list_id: function($stateParams) {
      return $stateParams.list_id;
    }
  },
  data: {
    authorizedRoles: [USER_ROLES.user],
    pageTitle: 'Lists'
  }
})

.state('dashboard.tododetail', {
  url: '/lists/:list_id/:todo_id',
  templateUrl: './partials/list.detail.html',
  controller: 'TodoDetailController',
  resolve: {
    list_id: function($stateParams) {
      console.log($stateParams);
      return $stateParams.list_id;
    },
    todo_id: function($stateParams) {
      console.log($stateParams);
      return $stateParams.todo_id;
    }
  }
})

<!-- ----------------Controllers  --------------------- ->  

app.controller("ListController", ['$rootScope', '$scope', '$state', '$q', 'UserService', '$window', 'AuthService', 'DataService', 'AUTH_EVENTS', 'list_id', '$mdSidenav',
  function($rootScope, $scope, $state, $q, UserService, $window, AuthService, DataService, AUTH_EVENTS, list_id, $mdSidenav) {
    $scope.value = 'this is value2';
    $rootScope.list_id = list_id.toString();
    $rootScope.todo_id = '';
    $scope.current_list = UserService.GetTodoBylistid($rootScope.lists, $scope.list_id);

    function toggleSidenav(menuId) {
      $mdSidenav(menuId).open();
    };

    $scope.Toggle_Todo_Detail = function(todo_id) {
      $state.go('dashboard.tododetail', {
        list_id: $scope.list_id,
        todo_id: todo_id
      }, {
        reload: false
      });

      toggleSidenav('right');
    };

  }
]);


app.controller("TodoDetailController", ['$rootScope', '$scope', '$state', '$q', 'UserService', '$window', 'AuthService', 'DataService', 'AUTH_EVENTS', 'list_id', '$mdSidenav', 'todo_id',
  function($rootScope, $scope, $state, $q, UserService, $window, AuthService, DataService, AUTH_EVENTS, list_id, $mdSidenav, todo_id) {

  }
]);
<!--  Main.html  -->

<div id="appContainer" md-theme="{{ dynamicTheme }}" ng-init="load()" md-theme-watch>
  <!-- Header Toolbar -->
  <div ui-view="header_toolbar"></div>

  <div layout="row" layout-xs="column" layout-sm="column">
    <!-- Sidenav right view -->
    <div ui-view="sidenavleft" id="nav_container"></div>

    <!-- Main middle container  -->
    <div flex="100" flex-gt-sm="55" layout="column" id="list_content">
      <md-content layout="column" flex class="md-padding">
        <div ui-view></div>
      </md-content>
    </div>

    <!-- Todo Detail View -->
    <div ui-view="todo_detail" id="todo_detail_view"></div>
  </div>
</div>

I don't want to pass data by $rootScope, and when I click on todo item, both to-do list and to do detail have to work, for now when I click on to do the middle template just vanishes out.

I am facing this issue because I have added my "Todo Detail View"outside UI view and I want to access data in "Todo Detail View"

Upvotes: 0

Views: 857

Answers (1)

MattDiMu
MattDiMu

Reputation: 5013

As the variable name $scope already hints, it's purpose is to be scoped and therefore not to be accessible from outside. The mentioned $rootScope is a way to communicate between well-connected childs/parents.

The "recommended" way to share data between different controllers is IMO usually angular services, which are injected in all controllers consuming or manipulating their data: https://docs.angularjs.org/guide/services

e.g. something like this

app.service('todoService', function() {
    var myTodos = [];
    this.addTodo = function (todo) {
        myTodos.push(todo);
    }
    this.getAllTodos = function(filter) {
       return myTodos.filter(filter);
    }
});

app.controller('firstController', function($scope, todoService) {
    // use todoService.addTodo() and such stuff
});

Upvotes: 1

Related Questions