在AngularJS中的控制器之间传递数据

时间:2016-03-17 16:00:20

标签: angularjs angularjs-service angularjs-controller 2-way-object-databinding

我试图在控制器之间传递数据,我做了一个服务来做到这一点。但不知何故,当我试图获取数据时,它不起作用。我不知道我的错误在哪里。这是代码:

这是AngularJS文件:

    var app = angular.module('Application', []);    

    app.controller('NotificationListController', function($scope,$http, NotificationService, Data) {
        var notificationList = NotificationService.getNotificationList();
        notificationList.then(function(response){
            console.log(response);
            $scope.notificationData = response.data;
            return response;
        });
        $scope.setEditedNotification = function(notification){
            $scope.editedNotification = Data.setNotificationValue(notification);
        }
    });

app.controller('NotificationEditController', function($scope, Data, TemplateService){
    $scope.editedNotification=Data.getNotificationValue();
});

app.service('Data', function(){
    var NotificationData;
    return{
        getNotificationValue: function(){
            return NotificationData;
        },
        setNotificationValue: function(notificationData){
            NotificationData = notificationData;
        }
    }
});

这是我的index.html

<tr ng-repeat="notification in notificationData">
            <td>{{notification.name}}</td>
            <td>{{notification.sender}}</td>
            <td>{{notification.subject}}</td>
            <td>{{notification.template.name}}</td>
            <td><a class="btn btn-default" href="editNotification.html" role="button" ng-click="setEditedNotification(notification)">Edit</a></td>
            <td><a class="btn btn-default" href="#" role="button" ng-click="deleteNotification(notification.id, $index)">Delete</a></td>
        </tr>

edit.html:

<div class="form-group col-md-offset-1">
            <label for="inputNotifName" class="col-sm-1 control-label">Name</label>
            <div class="col-md-6">
                <input ng-model="editedNotification.name" type="text" class="form-control" id="inputNotifName" placeholder="Notification name">
            </div>
        </div><br><br>
        <div class="form-group col-md-offset-1">
            <label for="inputNotifSender" class="col-sm-1 control-label">Sender</label>
            <div class="col-md-6">
                <input ng-model="editedNotification.sender" type="email" class="form-control" id="inputNotifSender" placeholder="Sender">
            </div>
        </div><br>
        <div class="form-group col-md-offset-1">
            <label for="inputNotifSubject" class="col-sm-1 control-label">Subject</label>
            <div class="col-md-6">
                <input ng-model="editedNotification.subject" type="text" class="form-control" id="inputNotifSubject" placeholder="Subject">
            </div>
        </div>

我调试了它,我发现当我调用Dara.setNotificationValue(notification);时,$ scope.editedNotification的值没有被更新。而且当我在设置后尝试获取var NotificationData时,该值仍然为null。我猜这个服务的方式有问题。

1 个答案:

答案 0 :(得分:0)

我将向您展示一个简化的样本,希望能让您走上正确的轨道。我通常不会写这一切,但我知道尝试自己从教程和示例中做到这一点是多么令人沮丧,这些教程和示例并不是你想做的。请注意,这是值得生产的代码 - 仅供说明之用。

首先是代码中包含问题的部分:

notificationList.then(function(response){
    console.log(response);
    $scope.notificationData = response.data;
    return response; <-- get rid of this
});

您不会从承诺的成功回调中返回任何内容,因为您没有分配任何内容。 在示例代码中,我伪造了这一部分,因为我无法访问您的API来检索数据。

app.service('Data', function(){
    var NotificationData;
    return{
        getNotificationValue: function(){
            return NotificationData;
        },
        setNotificationValue: function(notificationData){
            NotificationData = notificationData;
        }
    }
});

您的服务定义实际上是工厂。使用.service()时,必须使用this.来设置服务中的方法。要像您一样返回功能,您需要使用.factory()我在示例代码中使用了工厂。

$scope.setEditedNotification = function(notification){
    $scope.editedNotification = Data.setNotificationValue(notification);
}

在这里,您有效地将$scope.editedNotification设置为null。 在示例代码中,我使用了具有selectedNotification对象的getter / setter方法的工厂。我也在播放一个更改,因为在示例代码中,所有内容都在一个视图上。我强烈建议您使用路由解决方案,因为您在页面之间使用导航是导致空问题的原因 - 这是SPA的本质。

以下是示例代码。首先是JS:

var app = angular.module('Application', []);

app.controller('NotificationListController', function($scope, $http, Data, NotificationService) {
    /* below I'm faking up some data, this replaces the following code from your original post
     with corrections:
    var notificationList = NotificationService.getNotificationList();
    notificationList.then(function(response) {
        console.log(response);
        $scope.notificationData = response.data;
    }); */
    $scope.notificationData = NotificationService.getNotificationList();

    $scope.setEditedNotification = function(notification) {
        Data.notificationData = notification;
    };

    $scope.deleteNotification = function(notificationId) {
        // whatever you do to delete a notification
        Data.notificationData = {};
    };
});

app.controller('NotificationEditController', function($scope, Data) {
    // here I am responding to an event that is raised when setting the 
    // selected notification - you should handle this via routing within
    // your app
    $scope.$on('notificationSelected', function () {
        $scope.editedNotification = Data.notificationData;
    });
});

app.factory('Data', function($rootScope) {
    var _notificationData = {};
    var service = {
        get notificationData() {
            return _notificationData;
        },
        set notificationData(value) {
            _notificationData = value || {};
            $rootScope.$broadcast("notificationSelected");
        }
    }
    return service;
});

app.service('NotificationService', function() {
    this.getNotificationList = function() {
        return [{
            id: 1,
            name: "Notification 1",
            sender: "Sender 1",
            subject: "Subject 1",
            template: {
                name: "Template 1"
            }
        }, {
            id: 2,
            name: "Notification 2",
            sender: "Sender 2",
            subject: "Subject 2",
            template: {
                name: "Template 2"
            }
        }, {
            id: 3,
            name: "Notification 3",
            sender: "Sender 3",
            subject: "Subject 3",
            template: {
                name: "Template 3"
            }
        }];
    }
});

HTML:

<div ng-app="Application">
    <div ng-controller="NotificationListController">
        <table border="1">
            <tr ng-repeat="notification in notificationData">
                <td>{{notification.name}}</td>
                <td>{{notification.sender}}</td>
                <td>{{notification.subject}}</td>
                <td>{{notification.template.name}}</td>
                <td><a class="btn btn-default" href="editNotification.html" role="button" ng-click="setEditedNotification(notification); $event.preventDefault();">Edit</a></td>
                <td><a class="btn btn-default" href="#" role="button" ng-click="deleteNotification(notification.id, $index); $event.preventDefault();">Delete</a></td>
            </tr>
        </table>
    </div>
    <div ng-controller="NotificationEditController">
        Selecting a notification in the table above should cause it to be displayed here.
        <div>
            ID: {{editedNotification.id}}
            <br> Name: {{editedNotification.name}}
            <br> Sender: {{editedNotification.sender}}
            <br> Subject: {{editedNotification.subject}}
            <br> Template: {{editedNotification.template.name}}
        </div>
    </div>
</div>

还有一个JSFiddle供你修补。我希望这有帮助。有可能更好地构建这个部分或重构部分,但希望这可以让你开始。