AngularJS - Why does my factory not update the DOM?

38 views Asked by At

In my html I have:

<body ng-app='myApp'>
    <h1 ng-controller='controller'>
        {{YesOrNo}}
    </h1>
    <div ng-controller='controller'>
        <span>{{YesOrNo}}</span>
        <button ng-click='setYesOrNo()'>Click Me</button>
    </div>
    <script src='script.js'></script>
</body>

script.js:

const myApp = angular.module('myApp', [])

myApp.controller('controller', ['$scope', 'factory', function($scope, factory) {
    $scope.YesOrNo = factory.getYesOrNo()
    $scope.setYesOrNo = function() {
        $scope.YesOrNo = factory.setYesOrNo()
    }
}])

myApp.factory('factory', function() {
    let YesOrNo = 'Yes'
    return {
        getYesOrNo: function() { 
            return YesOrNo 
        },
        setYesOrNo: function() {
            YesOrNo = YesOrNo === 'Yes' ? 'No' : 'Yes'
            return YesOrNo
        }
    }
})

When I click the button, the span changes but h1 doesn't. Why is that? How do I get it to change?

EDIT: Sorry I should have been more clear. I want the two controllers to be separate. I want to know how to share scopes such that they both update when one of the them changes.

2

There are 2 answers

0
Tsvetan Ganev On

That's because you have set the ng-controller directive twice. This will create two separate instances of your controller with two separate scopes. The value in h1 will never change, because it is in a different scope than the one in the span tag - their values basically belong to two different objects. The button's event handler will only change the value in the corresponding controller - span's value will change and h1 will always stay the same.

Generally you never want to have two separate instances of the same controller (except for rare use-cases).

0
Sachila Ranawaka On

Don't duplicate the controller. Add it in one place.

<div ng-app='myApp'  ng-controller='controller'>
    <h1  >
        {{YesOrNo}}
    </h1>
    <div>
        <span>{{YesOrNo}}</span>
        <button ng-click='setYesOrNo()'>Click Me</button>
    </div>
    <script src='script.js'></script>
</div>

Demo

 
 
const myApp = angular.module('myApp', [])

myApp.controller('controller', ['$scope', 'factory', function($scope, factory) {
    $scope.YesOrNo = factory.getYesOrNo()
    $scope.setYesOrNo = function() {
        $scope.YesOrNo = factory.setYesOrNo()
    }
}])

myApp.factory('factory', function() {
    let YesOrNo = 'Yes'
    return {
        getYesOrNo: function() { 
            return YesOrNo 
        },
        setYesOrNo: function() {
            YesOrNo = YesOrNo === 'Yes' ? 'No' : 'Yes'
            return YesOrNo
        }
    }
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app='myApp'  ng-controller='controller'>
    <h1  >
        {{YesOrNo}}
    </h1>
    <div>
        <span>{{YesOrNo}}</span>
        <button ng-click='setYesOrNo()'>Click Me</button>
    </div>
    <script src='script.js'></script>
</div>