Angular JS将数据从工厂推送到控制器

时间:2014-10-28 21:10:20

标签: javascript html angularjs angularjs-scope angularjs-ng-repeat

我有一个带有输入字段的简单页面和一个用于更改名称的按钮。 按钮的ng-click时名称会发生​​变化,但我想要发生的事情是在hello {{name}}文本下面,以便记录选择的先前名称和选择它们的时间。 例如

你好汤姆

  • sam - 1414530148463
  • Mick - 1414530159015

我在这个小提琴http://jsfiddle.net/4ybmyf1a/2/中尝试了下面但是得到了消息,'无法读取未定义的属性推送'(我已经在myCtrl中注释掉了以便小提琴运行)

    <div ng-controller="MyCtrl">
        <input type="text" ng-model="updatedname" />
        <input type="button" value="Change name" ng-click="changeName(updatedname)"/>
        <br/>
          Hello, {{name}}!

    <ul>
        <li ng-repeat="names in namelog">{{nameLog.value}} - {{nameLog.time}}</li>
    </ul>    
    </div>


    var myApp = angular.module('myApp',[]);
    myApp.factory('UserService', function() {
                var userService = {};
                userService.name = "John";
                userService.ChangeName = function (value) {
                    userService.name = value;
                };
                userService.NameLog  = function (value) {
                    userService.nameLog.push ({
                        "value":value,
                        "time" :Date.now()
                    });
                };
        return userService;
    });

    function MyCtrl($scope, UserService) {
        $scope.name = UserService.name;
        $scope.updatedname="";
        $scope.changeName=function(data){
            $scope.updateServiceName(data);
        }
        $scope.updateServiceName = function(name){
            UserService.ChangeName(name);
            //UserService.NameLog(name);
            $scope.name = UserService.name;
            //$scope.nameLog = UserService.NameLog;
        }
    }

我已经看过还添加了userService.nameLog = []来停止未定义的问题但是这并没有像我想要的那样推送项目。

        userService.NameLog  = function (value) {
            userService.nameLog = [];
            userService.nameLog.push ({
                "value":value,
                "time" :Date.now()
            });
        };

我怎么能够实现这个目标?

3 个答案:

答案 0 :(得分:2)

这是你的第一个问题:

<li ng-repeat="names in namelog">{{nameLog.value}} - {{nameLog.time}}</li>

您应该在此ng-repeat中访问的变量是names,因此这是正确的形式(我还将变量重命名为更有意义):

<li ng-repeat="logEntry in namelog">{{logEntry.value}} - {{logEntry.time}}</li>

第二个问题是你的控制器,这是一个正确的版本:

function MyCtrl($scope, UserService) {
    $scope.name = UserService.name;
    // Add the name log to the scope here, not when you
    // invoke the updateServiceName function
    $scope.namelog = UserService.nameLog;

    $scope.changeName = function(data){
        $scope.updateServiceName(data);
    }

    $scope.updateServiceName = function(name){
        UserService.ChangeName(name);
        UserService.NameLog(name);
        $scope.name = UserService.name;
    }
}

在您的版本中,您已注释掉以下代码:

//$scope.nameLog = UserService.NameLog;

这有两个原因是错误的。首先,nameLog变量的大小写在控制器和模板中是不同的(nameLog vs namelog)。其次,你将它分配给NameLog函数而不是nameLog属性(再次注意案例)。

当我在你的小提琴中进行这些修改时,它开始正常工作。

顺便说一句,我认为更改用户名时添加日志条目的逻辑应该在服务本身而不是控制器函数中。

答案 1 :(得分:2)

结合不同的事情。

您的工厂函数LogName在推送日志条目时引用自身。这是你想要在服务对象(_nameLog)之外声明的东西,并使用闭包将其返回(getNameLog

myApp.factory('UserService', function() {
        var _nameLog = [];
        var userService = {};
        userService.name = "John";
        userService.ChangeName = function (value) {
            userService.name = value;
        };
        userService.logName  = function (value) {
            _nameLog.push ({
                "value":value,
                "time" :Date.now()
            });
        };
        userService.getNameLog = function(){ return _nameLog; }
        return userService;
});

您还错误地使用了ng-repeat:

<li ng-repeat="name in nameLog">{{name.value}} - {{name.time}}</li>

以下是工作版本:http://jsfiddle.net/sfqo2fn3/

答案 2 :(得分:1)

在更改了一些内容之后,我用一个工作版本更新了jsfiddle。请参考。

http://jsfiddle.net/4ybmyf1a/4/

这些是变化

 <li ng-repeat="names in nameLog">{{names.value}} - {{names.time}}</li>


myApp.factory('UserService', function() {
            var userService = {};
            var nameLog = [];
            userService.name = "John";

            userService.ChangeName = function (value) {
                userService.name = value;
            };

            userService.addNameToLog  = function (value) {
                nameLog.push ({
                    "value":value,
                    "time" :Date.now()
                });
                return nameLog;
            };

    userService.getNameLog = function() {
        return nameLog;
    }

    return userService;
});

控制器

function MyCtrl($scope, UserService) {
    $scope.name = UserService.name;
    $scope.updatedname="";

    $scope.changeName = function(data){
        $scope.updateServiceName(data);
    }

    $scope.updateServiceName = function(name){
        UserService.ChangeName(name);
        UserService.addNameToLog(name);
        $scope.name = UserService.name;
        $scope.nameLog = UserService.getNameLog();
        console.log(JSON.stringify($scope.nameLog));
    }
}