【问题标题】:Data does not pass through service to other controller数据不通过服务传递给其他控制器
【发布时间】:2020-12-30 15:17:12
【问题描述】:

我试图将我的数据从控制器 1 传递到控制器 2,但是当我在控制器 2 中记录数据时,它返回一个未定义的值。我之所以使用 jquery 来请求数据是因为我使用的是数据表,我不知道如何使用 angularjs 和数据表框架进行事件绑定。我想知道根据控制器 1 向其发送数据,我的工厂服务实现是否正确,因为我认为这就是我现在的问题所在。数据未经过工厂服务。

工厂服务

app.factory('profilingFactory', function() {
    var factoryData = {};
    var factoryModel = {};
    
    factoryData.setModel = function(key, value) {
        factoryModel[key] = value;
    }
    
    factoryData.getModel = function(key) {
        return factoryModel[key];
    };
    
    return factoryData;
    
});

控制器 1

app.controller('profilingController', function($scope, $http, $window, profilingFactory) {
    
    $(document).ready(function() {
        
        
        $scope.table = $('#table_profile').DataTable ({
            "ajax": {
                "url": "/getProfilesData",
            },
            "columns": [
                {"data": "applicant_id"},
                {"data": "application_type"},
                {"data": "last_name"},
                {"data": "middle_name"},
                {"data": "first_name"},
                {"data": "birth_date"},
                {"data": "address"},
                {"data": "sex"},
                {"data": "date_applied"},
                {
                    "data": "applicant_id",
                    "mRender":  function (data, type, full) {
                        var editLink = '<button id="editFunc" class="btn btn-primary" type="button" data-id="' + data + '">Edit</button>';
                        //var editLink = '<a id="editFunc" class="editFunction" href="/editProfiles?applicant_id=' + data + '">Edit</a>';
                        var deleteLink = '<button class="btn btn-primary" id="deleteButtonFunc" type="button" data-id="'+ data +'">Delete</button>';
                        return (editLink + " " + "  |  " + " " + deleteLink);
                    }
                }
            ]
        });

        $('body').on('click', '#editFunc', function(e) {
            
            var clickedEdit = $(this);
            var id = clickedEdit.attr("data-id");
            var url = "/editProfiles?applicant_id=" + id;
            var editData = {
                    editId: id
            }
            //$(location).attr('href', url);
            $http.get('/getEditProfilesData/', {params: editData}).then(function(response) {
                //this is orignally what I inteded. I only put a string to test if the service is working
                profilingFactory.setModel('proFactor', response.data);
            });
            
        });
        
        
        $scope.stringXample = "Yeh";
        //$scope.editProfiles = appData;
        
        $('body').on('click', '#deleteButtonFunc', function(e){
        
            var clicked = $(this);
            var id = clicked.attr("data-id");
            
            var deleteData = {
                    deleteId: id
            }
            
            $http.get('/delProfileData/', {params: deleteData}).then(function(response) {
                clicked.parents("tr").remove();
                alert("User info successfully removed");
            });
            //Optional delete Row after 
        });
        
    });
    

控制器 2

app.controller('editProfliesController', function($scope, $http, $window, profilingFactory) {
    $scope.value = profilingFactory.getModel('proFactor');
    console.log($scope.value);
});

HTML

<div class="row">
                    <h1 class="header-edit">Basic Information</h1>
                    <div class="col-md-3">
                        <div class="form-group">
                            <label for="pwd">Last Name:</label> <input type="text"
                                class="form-control" name="pwd" value="{{appData.last_name}}">
                        </div>
                    </div>

                    <div class="col-md-3">
                        <div class="form-group">
                            <label for="email">First Name:</label> <input type="text"
                                class="form-control" name="email" value="{{appData.first_name}}">
                        </div>
                    </div>

                    <div class="col-md-3">
                        <div class="form-group">
                            <label for="pwd">Middle Name:</label> <input type="text"
                                class="form-control" name="pwd">
                        </div>
                    </div>

                    <div class="col-md-3">
                        <div class="form-group">
                            <label for="pwd">Birth:</label> <input type="date"
                                class="form-control" name="pwd" >
                        </div>
                    </div>
                </div>

【问题讨论】:

  • 这种行为可能是因为您在 Promise 中执行 setModel。看起来在您的承诺可以在 Controller 1 中解决之前,Controller 2 正在加载。为了确认这一点,您可以尝试将 setModel 移出 http.get 并查看它是否有效?
  • 我尝试在 $http 中移出 setModel,但它仍然返回未定义的值。

标签: jquery angularjs datatables


【解决方案1】:

我在本地尝试了您的代码。让我根据我的理解先详细说明这个问题。

Controller1 和 Controller2 已在初始页面呈现时加载。一旦加载,Controller2 的“功能”将不再执行。 在 Controller1 中完成 $http.get 后,您实际上需要再次触发它的一部分。 您可以使用 $watch (https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch) 来实现它。

仅将您的 setModel 保留在 $http.get 中,并将您的 Controller2 逻辑更改为以下,然后重试:

app.controller('editProfliesController', function ($scope, $http, $window, profilingFactory) {
                $scope.$watch(function () { return profilingFactory.getModel('proFactor') }, function (newVal, oldVal) {
                    if (newVal!==oldVal)
                    console.log(newVal);
                });
            });

完整代码(最小可重现示例)

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script>
    var app = angular.module('myApp', []);
    app.factory('profilingFactory', function () {
        var factoryData = {};
        var factoryModel = {};

        factoryData.setModel = function (key, value) {
            factoryModel[key] = value;
        }

        factoryData.getModel = function (key) {
            return factoryModel[key];
        };
        return factoryData;
    });

    app.controller('profilingController', function ($scope, $http, $window, profilingFactory) {

        $(document).ready(function () {
            $('body').on('click', '#editFunc', function (e) {
                                
                //$(location).attr('href', url);
                $http.get('/getEditProfilesData/', { params: "" }).then(function (response) {
                    // I will not land here since call will fail for me. I am setting model in fail function below
                    // profilingFactory.setModel('proFactor', "hello world");
                }, function (response) {
                        profilingFactory.setModel('proFactor', "hello world");
                });

            });
            $scope.stringXample = "Yeh";
            //$scope.editProfiles = appData;
            $('body').on('click', '#deleteButtonFunc', function (e) {

                var clicked = $(this);
                var id = clicked.attr("data-id");

                var deleteData = {
                    deleteId: id
                }

                $http.get('/delProfileData/', { params: deleteData }).then(function (response) {
                    clicked.parents("tr").remove();
                    alert("User info successfully removed");
                });
                //Optional delete Row after 
            });
        });
            });
            app.controller('editProfliesController', function ($scope, $http, $window, profilingFactory) {
                $scope.$watch(function () { return profilingFactory.getModel('proFactor') }, function (newVal, oldVal) {
                    if (newVal!==oldVal)
                        console.log(newVal);
                });
            });
    </script>
<body>

    <div ng-app="myApp">
        <input type="button" id="editFunc" value="Edit"/>
        <div ng-controller="profilingController"></div>
        <div ng-controller="editProfliesController"></div>
    </div>

</body>
</html>

【讨论】:

  • 我尝试了这个解决方案,但它没有记录任何内容。似乎它没有读取控制器 2 中的代码(不确定这个),因为它没有显示 newVal 的日志是什么,甚至没有显示它是否未定义或其他任何内容。但是当我在 $scope.$watch 之外记录一串单词时,它会记录一个值。
  • 可能是我的服务工厂没有设置好从控制器 1 获取数据吗?
  • 当我尝试时它在本地运行良好。您可以尝试登录 controller1 以检查您的出厂模型是否设置正确。你也可以分享html吗?只是想看看那里如何使用控制器。您可以更新问题。
  • 还要查看控制台中是否有任何错误。验证http get是否成功
  • 我更新了帖子。顺便说一句,控制台中没有错误,如果请求中有错误,我检查了网络,但结果一切都很好。哦,顺便说一句,你也在本地设置中使用这篇文章中的服务(只是想澄清一下,也许你以不同的方式声明它)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-12
  • 2019-07-16
  • 1970-01-01
  • 1970-01-01
  • 2017-03-24
相关资源
最近更新 更多