简体   繁体   中英

AngularJS - access elements outside of ng-view

I have a setup with an ng-view (an admin panel) that lets me display orders. I have a search box outside of ng-view that I would like to use to modify my json request. I've seen some posts on accessing things such as the title but was not able to get them to work - perhaps outdated.

Main app stuff:

angular.module('myApp', ['myApp.controllers', 'myApp.filters', 'myApp.services', 'myApp.directives', 'ui.bootstrap']).
config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider)       {

$routeProvider.
  when('/', {
    templateUrl: '/partials/order/manage.html',
    controller: 'ManageOrderCtrl'
  }).     
  when('/order/:id', {
   templateUrl: '/partials/order/view.html',
    controller: 'ViewOrderCtrl'
  }).   
  otherwise({
    redirectTo: '/'
  });
$locationProvider.html5Mode(true);
}]);

Manage controller:

angular.module('myApp.controllers', [])
.controller('ManageOrderCtrl', ['$scope', '$http', '$dialog', 'config', 'Page', function($scope, $http, $dialog, config, Page) {

  // would like to have search value from input #search available here
  var getData = function() {
    $http.get('/orders').
    success(function(data, status, headers, config) {
      $scope.orders = data.orders;
    });
  };

getData();
})

View:

<body ng-app="myApp" >
  <input type="text" id="search">
  <div class="ng-cloak" >
    <div ng-view></div>
  </div>
</body>

If you're going to access stuff outside the <div ng-view></div> , I think a better approach would be to create a controller for the outer region as well. Then you create a service to share data between the controllers:

<body ng-app="myApp" >
  <div ng-controller="MainCtrl">
      <input type="text" id="search">
  </div>
  <div class="ng-cloak" >
    <div ng-view></div>
  </div>
</body>

( ng-controller="MainCtrl" can also be placed on the <body> tag - then the ng-view $scope would be a child of the MainCtrl $scope instead of a sibling.)

Creating the service is as simple as this:

app.factory('Search',function(){
  return {text:''};
});

And it's injectable like this:

app.controller('ManageOrderCtrl', function($scope,Search) {
  $scope.searchFromService = Search;
});

app.controller('MainCtrl',function($scope,Search){
  $scope.search = Search;
});

This way you don't have to rely on sharing data through the global $rootScope (which is kinda like relying on global variables in javascript - a bad idea for all sorts of reasons) or through a $parent scope which may or may not be present.

I've created a plnkr that tries to show the difference between the two solutions.

You can use scope hierarchies .

Add an "outer" ng-controller definition to your HTML like this:

<body ng-controller="MainCtrl">

It will become the $parent scope. But you do not need to share data by using a service. You don't even need to use the $scope.$parent scope. You can use scope hierarchies . (See the Scope Hierarchies section on that page). It is really easy.

In your MainCtrl , you may have this:

$scope.userName = "Aziz";

Then in any controller that is nested within MainCtrl (and does not override the userName in its own scope) will have userName also! You can use in in the view with {{userName}}.

Try this...

View:

<body ng-app="myApp" >
  <input type="text" id="search" ng-model="searchQuery" />
  <div class="ng-cloak" >
    <div ng-view></div>
  </div>
</body>

Using it in your controller:

$http.get('/orders?query=' + $scope.searchQuery).
    success(function(data, status, headers, config) {
      $scope.orders = data.orders;
});

Basically, you can do that with anything INSIDE ng-app... Move your ng-app to the html tag and you can edit the title as well!

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM