简体   繁体   中英

AngularJS: $on doesn't work

I am trying to make it possible to edit user name in modal window using AngularJS, however, after I use "update()" function from my second controller, name remains the same. $scope.closeThisDialog(); works fine. What's wrong with my $on and $emit ?

My service:

  'use strict';
    var myService = function () {
        var user = { name: "Peter", surname: "Pitt"};   
        var service = {};
        service.user = user;
        return service;
    };
    module.exports = [myService];

First controller:

    'use strict';   
    var FirstController = function ($scope, myService, ngDialog) {   
        $scope.user = myService.user;   
        $scope.openModal = function () {
            ngDialog.open({templateUrl: 'myTemplate'});
        };  
        $scope.$on("updateUser", function(event, data){
            $scope.user = data;
        });
    };
    module.exports = ['$scope', 'myService', 'ngDialog', FirstController];

Second controller:

'use strict'; 
var SecondController = function ($scope, myService, ngDialog) {
    $scope.editedUser = angular.copy(myService.user); 
    $scope.update = function () {
            $scope.$emit("updateUser", $scope.editedUser);
            $scope.closeThisDialog();
        };
    };    
    module.exports = ['$scope', 'myService', 'ngDialog', SecondController];

index file:

<html>
<body ng-app="">
    <div ng-controller="FirstController">
        <a ng-click="openModal()">Edit</a>
        Name: {{user.name}} </br>
        Surname: {{user.surname}}
    </div>
</body>
</html>

and modal window:

<script type="text/ng-template" id="edit">
    <form ng-controller="SecondController">
        <input ng-model="editedUser.name">
        <input ng-model="editedUser.surname">
        <button ng-click="update()">Submit</button>
    </form>
</script>

It's because $emit only echo's the event up the scope chain. So your first controller would only hear if it it's scope was a parent (or parents parent etc...) of your second controller.

In order for the event to work you'll have to use $rootScope.$on (capture everything going up) in your first controller OR $rootScope.$broadcast (send event to every child scope) in your second controller.

You can also do this without using the $emit and $broadcast if you just want the data to be updated in the FirstController by replacing

$scope.update = function () {
        $scope.$emit("updateUser", $scope.editedUser);
        $scope.closeThisDialog();
    };
};  

with

 $scope.update = function () {
        angular.copy($scope.editedUser,myService.user); 
        $scope.closeThisDialog();
    };
}); 

You can see a working fiddle here

Looks like you need to pass the $scope into ngDialog.open so that you are emitting on the same scope you are listening on:

ngDialog.open({ template: 'myTemplate', scope: $scope });

of course, since you are now sharing the same scope, you should just be able to edit $scope.user directly in the modal and not bother emitting/listening for events at all ;)

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