0

I have one controller to get all records from table1. In table2, I have a foreign key to table1. With machineController I managed to populate select tag in html. But want on post to fill sparePartController. From some reason this is not working, I made a mistake somewhere, could you help me understand where?

<div ng-app="app" ng-controller="sparePartController as vm">
    <div class="form-group" ng-controller="machineController as machineVM">
        <label>Machine Type</label>
        <select class="form-control" ng-model="vm.newSparepart.machine" ng-options="machine.name for machine in machineVM.machines"></select>
    </div>
</div>

//sparePartController.js
(function () {
    "use strict";

    angular.module("app")
        .controller("sparePartController", sparePartController);

    function sparePartController($http)
    {
        var vm = this;

        vm.spareParts = [];
        vm.newSparePart = {};

        vm.errorMessage = "";
        vm.isBusy = true;

        $http.get("/spares/getAll")
            .then(function (response) {
                //success
                angular.copy(response.data, vm.spareParts);
            }, function (error) {
                vm.errorMessage = error;
            }).finally(function () {
                vm.isBusy = false;
            });

        vm.addSparePart = function () {
            vm.isBusy = true;
            vm.errorMessage = "";

            $http.post("/spares", vm.newSparePart)
                .then(function (response) {
                    alert("Test");
                    vm.spareParts.push(response.data);
                    vm.newSparePart = {};
                }, function () {
                    alert(vm.data);
                    vm.errorMessage = "failed to save new spare";
                }).finally(function () {
                    vm.isBusy = false;
                });
        };
    }
})();

// machineController.js
(function () {
    "use strict";

    angular.module("app")
        .controller("machineController", machineController);

    function machineController($http) {
        /* jshint validthis:true */
        var vm = this;

        vm.machines = [];
        vm.newMachine = {};

        vm.errorMessage = "";
        vm.isBusy = true;

        $http.get("/machines/GetMachines")
            .then(function (response) {
                // Success
                angular.copy(response.data, vm.machines);
            }, function (error) {
                // Failure
                vm.errorMessage = "Failed: " + error;
            }).finally(function () {
                vm.isBusy = false;
            });

            vm.addMachine = function () {
                vm.isBusy = true;
                vm.errorMessage = "";
            $http.post("/machines", vm.newMachine)
                .then(function (response) {
                    vm.machines.push(response.data);
                    vm.newMachine = {};
                }, function () {
                    //fail
                    vm.errorMessage = "Failed to save new machine type";
                }).finally(function () {
                    vm.isBusy = false;
                });
        };
    }
})();

Can you please check this, where am I wrong ? Code to check

Danijel Boksan
  • 779
  • 1
  • 13
  • 30

2 Answers2

1

Scopes in Angular use prototypical inheritance i.e all the parent properties are accessible to children. When trying to access a property in child scope the interpreter traverses the prototype chain starting from the child and moving up the parent chain and not the other way around i.e You want get the hold of child properties in parent scope.

In simple words. You can't access child scopes from parents.

So what is the solution for this problem.

  1. Define properties in the parent scope and use in child

  2. Use service/rootscope(not recommended) to share data between controllers

  3. Communicate between controllers using $emit or $broadcast

The choice of the which technique to use is totally yours and depends on the type of application that you are working on. So choose wisely.

Below is one such example using service that helps you to share data between two controllers

var myApp = angular.module('myApp', []);
myApp.service('Data', function() {
  this.message = "I'm data from a service";
  this.secondMessage = "Another Data in service";
})

function FirstCtrl($scope, Data) {
  $scope.data = Data;
}

function SecondCtrl($scope, Data) {
  $scope.data = Data;
}

function thirdCtrl($scope, Data) {
  $scope.data = Data;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
  <div ng-controller="FirstCtrl">
    <h1>Controller 1</h1>
    <input type="text" ng-model="data.message">
    <h1>{{data.message}}</h1>
  </div>

  <div ng-controller="SecondCtrl">
    <h1>Controller 2</h1>
    <input type="text" ng-model="data.secondMessage">
    <h1>{{data.message}}</h1>
  </div>

  <div ng-controller="thirdCtrl">
    <h1>Controller 3</h1>
    <input type="text" ng-model="data.secondMessage">
    <h1>{{data.secondMessage}}</h1>
  </div>
</div>

Reference : Discussion on Share data from child to parent controller

In Depth Scope Inheritance in Angular

Hope this helps :)

Manish
  • 4,692
  • 3
  • 29
  • 41
  • I'd disagree with point 2 and 3. (2) would be useful in larger applications, whereas (3) could get very expensive and convoluted in larger applications, so really it depends on what he's building. However, in his case, (1) is most likely to be more useful. – rrd Jul 11 '17 at 10:50
  • I agree with you. It totally depends on the application. I have not stated any preference have just listed down the various options available. The is totally upon the user whatever he feels the best fit will be in his case. – Manish Jul 11 '17 at 10:53
  • Since I'm quiet new in Angular, with your example how can I use in my files where every controller is separately. If you use one parent controller and 2 child, but those two child will give value to different properties, how it should be than? like your example just add one more controller ? – Danijel Boksan Jul 11 '17 at 11:01
  • similary you can have as many controllers as you want just inject your service as a dependency to each controller and also in your service you can have as many properties as you want. Updated my answer for three controllers and two different properties in service – Manish Jul 11 '17 at 13:16
  • @DanijelBoksan have updated the fiddle. As you are using the controller as syntax you need to use the controller while binding the value to UI. [Updated Fiddle](https://jsfiddle.net/manishjanky/hgmptd8t/2/) – Manish Jul 12 '17 at 13:11
  • Thank you very much, you helped me a lot to solve my problem. – Danijel Boksan Jul 13 '17 at 08:02
0

please apply this code,it will work.

var testCtrl1ViewModel = $scope.$new();

 $controller('childControllerName', {$scope: testCtrl1ViewModel});
Rohit Poudel
  • 1,793
  • 2
  • 20
  • 24