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

时间:2022-08-24 17:36:33

I have a simple page with an input field and a button to change the name. The name changes on ng-click of the button, but what I want to happen is below the hello {{name}} text to have a log of the previous names selected and the time they were selected. eg

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

Hello Tom

你好汤姆

  • sam - 1414530148463
  • 山姆 - 1414530148463
  • Mick - 1414530159015
  • 米克 - 1414530159015

I have tried the below in this fiddle http://jsfiddle.net/4ybmyf1a/2/ but get the message, 'cannot read property push of undefined' (I have commented out in myCtrl so that the fiddle would run)

我在这个小提琴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;
        }
    }

I have looked at also adding in userService.nameLog = [] to stop the undefined issue however this does not push the items like I want it.

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

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

How am I able to acheive this?

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

3 个解决方案

#1


2  

Couple different things.

夫妻不同的事情。

Your factory function LogName was referencing itself when pushing the log entry. This is the sort of thing you want to declare outside of the service object (_nameLog) and use a closure to return it back (getNameLog)

在推送日志条目时,工厂函数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;
});

You were also using the ng-repeat incorrectly:

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

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

Here is a working version: http://jsfiddle.net/sfqo2fn3/

这是一个工作版本:http://jsfiddle.net/sfqo2fn3/

#2


2  

This is your first problem:

这是你的第一个问题:

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

the variable you should be accessing in this ng-repeat is names, so this is the correct form (I also renamed the variable to make more sense):

你应该在这个ng-repeat中访问的变量是名称,所以这是正确的形式(我还重命名了变量以使其更有意义):

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

And second problem is your controller, here is a correct version:

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

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;
    }
}

In your version, you have commented out the following code:

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

//$scope.nameLog = UserService.NameLog;

That is wrong for two reasons. First the case of the nameLog variable is different in the controller and in the template (nameLog vs namelog). Second your are assigning it reference to the NameLog function not the nameLog property (again, notice the case).

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

When I made these modifications in your Fiddle it started working correctly.

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

And by the way, I think that the logic for adding log entry when you change username should be in the service itself not in the controller function.

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

#3


1  

I updated the jsfiddle with a working version after changing few things. Please refer it.

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

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

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

These are the changes

这些是变化

 <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;
});

Controller

调节器

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));
    }
}

#1


2  

Couple different things.

夫妻不同的事情。

Your factory function LogName was referencing itself when pushing the log entry. This is the sort of thing you want to declare outside of the service object (_nameLog) and use a closure to return it back (getNameLog)

在推送日志条目时,工厂函数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;
});

You were also using the ng-repeat incorrectly:

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

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

Here is a working version: http://jsfiddle.net/sfqo2fn3/

这是一个工作版本:http://jsfiddle.net/sfqo2fn3/

#2


2  

This is your first problem:

这是你的第一个问题:

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

the variable you should be accessing in this ng-repeat is names, so this is the correct form (I also renamed the variable to make more sense):

你应该在这个ng-repeat中访问的变量是名称,所以这是正确的形式(我还重命名了变量以使其更有意义):

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

And second problem is your controller, here is a correct version:

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

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;
    }
}

In your version, you have commented out the following code:

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

//$scope.nameLog = UserService.NameLog;

That is wrong for two reasons. First the case of the nameLog variable is different in the controller and in the template (nameLog vs namelog). Second your are assigning it reference to the NameLog function not the nameLog property (again, notice the case).

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

When I made these modifications in your Fiddle it started working correctly.

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

And by the way, I think that the logic for adding log entry when you change username should be in the service itself not in the controller function.

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

#3


1  

I updated the jsfiddle with a working version after changing few things. Please refer it.

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

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

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

These are the changes

这些是变化

 <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;
});

Controller

调节器

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));
    }
}