Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using same controller in two places in AngularJS

I am working on an Ionic app, screen has lists with checkboxes and option to select all. I am new to AngularJS and Ionic.

"Select All" works fine when using controller in parent element where Select all and other lists reside.

I want to move the Select All to sub-header so that "Select All" will be always visible when we scroll through.

I tried to use the same controller in both places but Select All didn't work, I just read the scope gets changed and the value won't get passed.

Is there any way to pass the changes or any other way to fix this?

And data will be populated from the services.

HTML

 <ion-header-bar class="bar-light bar-subheader">
   <div ng-controller="MainCtrl">
      <ion-checkbox ng-model="selectAll" ng-click="checkAll()" >
          <p>Select All</p>
      </ion-checkbox>
    </div>
</ion-header-bar>
<ion-content class="has-header">
  <div class="list" ng-controller="MainCtrl">    
    <ion-checkbox ng-repeat="item in devList" ng-model="item.checked">
      <div class="row">
        <div class="col">
          <p>{{ item.text }} - 99</p>
          <p>{{ item.text }} - 99</p>
        </div>
         <div class="col right">
          <p>{{ item.text }} - 99</p>
           <p>{{ item.text }} - 99</p>
        </div>
      </div>
    </ion-checkbox>
  </div>
</ion-content>  

JS

.controller('MainCtrl', function($scope) {
  $scope.devList = [
    { text: "HTML5", checked: true },
    { text: "CSS3", checked: false },
    { text: "JavaScript", checked: false }
  ];

   $scope.checkAll = function() {    
        if ($scope.selectAll) {
            $scope.selectAll = true;
        } else {
            $scope.selectAll = false;
        }
        angular.forEach($scope.devList, function (item) {
            item.checked = $scope.selectAll;
        });
    };
});

CodePen link

like image 526
Shankar Avatar asked May 01 '16 18:05

Shankar


People also ask

How can we share the data between controllers in AngularJS?

Approach: To share data between the controllers in AngularJS we have two main cases: Share data between parent and child: Here, the sharing of data can be done simply by using controller inheritance as the scope of a child controller inherits from the scope of the parent controller.

Can we inject one controller into another controller in AngularJS?

You can't inject controllers into one another. Yes, you should change TestCtrl1 into a service instead.

Can we have two controllers in AngularJS?

An AngularJS application can contain one or more controllers as needed, in real application a good approach is to create a new controller for every significant view within the application. This approach will make your code cleaner and easy to maintain and upgrade. Angular creates one $scope object for each controller.

Can we have nested controllers in AngularJS?

Nested Controllers: AngularJS allows using nested controllers. It means that you have specified a controller in an HTML element which is a child of another HTML element using another controller.


2 Answers

Each controller will have it's own $scope. So, two different instances of controllers might have the same code, but they will still have different scopes.

So, you want to pass the changes from one controller to another. In that case, there are a few solutions:

Using events:

$scope has a few methods which can help you to handle these cases.

These methods:

$on(name, listener) - Listens on events of a given type/name.

$emit(name, args) - Dispatches an event name upwards through the scope hierarchy notifying the registered $rootScope.Scope listeners.

$broadcast(name, args) - Dispatches an event name downwards to all child scopes (and their children) notifying the registered $rootScope.Scope listeners.

These methods will allow you to rise events from one controller and handle them inside the others.

Shared services

Also, you can create the service which will be injected into different controllers and, lets say, first controller will read this shared data and the second will write the data to this shared service. Here is an article with some examples - link.

You can chose the approach that you like more, but I prefer shared services. This approach keeps my controllers more clear and I can manage cross-controllers dependencies by injection this shared services.

Hope it will help you.

like image 176
MaKCbIMKo Avatar answered Sep 28 '22 07:09

MaKCbIMKo


You cannot use 2 'ng-controllers' with same controllers because the scopes created from those 2 controllers will be different, as controller scopes are created using the constructor pattern.

Ideally you should use $stateProvider to define your routes and their corresonding template and controller like below:

But for simplicity sake I have forked your codepen and used a single controller at the parent level of the view and it is working fine: http://codepen.io/anon/pen/vGQJNj

<body  ng-controller="MainCtrl">

<ion-header-bar class="bar-positive">
  <h1 class="title">Checkboxes</h1>
</ion-header-bar>

<ion-header-bar class="bar-light bar-subheader">
      <div>
            <ion-checkbox ng-model="selectAll" ng-click="checkAll()" >

              <p>Select All</p>
  </ion-checkbox>
      </div>

  </ion-header-bar>

<ion-content class="has-header">

  <div class="list">

    <ion-checkbox ng-repeat="item in devList"
                  ng-model="item.checked" 
                  ng-checked="item.checked">
      <div class="row">
        <div class="col">
          <p>{{ item.text }} - 99</p>
          <p>{{ item.text }} - 99</p>
        </div>
         <div class="col right">
          <p>{{ item.text }} - 99</p>
           <p>{{ item.text }} - 99</p>
        </div>
      </div>
    </ion-checkbox>

    <div class="item">
      <pre ng-bind="devList | json"></pre> 
    </div>

    <div class="item item-divider"> 
      Notifications
    </div>

    <ion-checkbox ng-model="pushNotification.checked"
                  ng-change="pushNotificationChange()">
      Push Notifications
    </ion-checkbox>

    <div class="item">
      <pre ng-bind="pushNotification | json"></pre> 
    </div>

    <ion-checkbox ng-model="emailNotification"
                  ng-true-value="'Subscribed'"
                  ng-false-value="'Unubscribed'">
      Newsletter
    </ion-checkbox>
    <div class="item">
      <pre ng-bind="emailNotification | json"></pre> 
    </div>

  </div>

</ion-content>

</body> 
like image 23
Aditya Singh Avatar answered Sep 28 '22 07:09

Aditya Singh