【问题标题】:AngularJS - Service shared between two controllers with async callAngularJS - 通过异步调用在两个控制器之间共享服务
【发布时间】:2014-10-16 22:59:48
【问题描述】:

我是 Angular 新手,但遇到了一些问题...

我有两个指令共享同一个控制器,并且该控制器是一个服务,在异步调用 ($http) 上请求 json 文件。

指令需要相同的数据,并且几乎同时初始化,但我只想进行一次调用并将数据检索到控制器并使用数据更新视图。

MainMenuHeader.js

(function () {
var app = angular.module("mainMenuHeaderModule", ["mainMenuControllerModule"]);

app.directive("mainheader", function () {
    return {
        restrict: "A",
        transclude: true,
        templateUrl: "TMainMenuHeader.html",
        controller: "mainMenuController",
    }
});})();

MainMenuAside.js

(function () {
var app = angular.module("mainMenuAsideModule", ["mainMenuControllerModule"]);

app.directive("mainaside", function () {
    return {
        restrict: "A",
        transclude: true,
        templateUrl: "TMainMenuAside.html",
        controller: "mainMenuController"
    }
});})();

MainMenuController.js

        (function () {
        var app = angular.module("mainMenuControllerModule", ["mainMenuServiceModule"]);

        app.controller("mainMenuController", ["$scope", "MainMenuService",
            function ($scope, MainMenuService)
            {

                $scope.menuList = MainMenuService.GetAsyncData();

                console.log("mainMenuController menuList: " + $scope.menuList);
        }]);
    })
();

MainMenuService.js

    (function () {
    var module = angular.module("mainMenuServiceModule", []);

    module.factory("MainMenuService", ["$q", "$http", function ($q, $http)
    {
        var data;

        var getAsyncData = function()
        {
            console.log(" -> getting data...");
            $http.get("menu.json")
            .success(function(result)
            {
                data = result;

                console.log("async data: " + data);
            });

             return data;
        }


        var getDataObject = function ()
        {
            return [
                        {
                            id:1,
                            title: "Menu 1",
                            submenus: [
                                {
                                    title: "Sub Menu 1",
                                    itens: [
                                        { title: "Option 1" },
                                        { title: "Option 2" },
                                        { title: "Option 3" }
                                    ]
                                }
                            ]
                        },
                        {
                            id:2,
                            title: "Menu 2",
                            submenus: [
                                {
                                    title: "Sub Menu 2",
                                    itens: [
                                        { title: "Option 1" },
                                        { title: "Option 2" },
                                        { title: "Option 3" },
                                        { title: "Option 4" },
                                        { title: "Option 5" }
                                    ]
                                }
                            ]
                        },
                        {
                            id:3,
                            title: "Menu 3",
                            submenus: [
                                {
                                    title: "Sub Menu 3",
                                    itens: [
                                        { title: "Option 1" },
                                        { title: "Option 2" },
                                        { title: "Option 3" }
                                    ]
                                }
                            ]
                        }
                    ];
        }

        return {
            GetDataObject : function()
            {
                return getDataObject();
            },

            GetAsyncData : function()
            {
                return getAsyncData();
            }
        }
    }]);
})();

服务有两种方法。 一个返回一个 JS 对象仅用于测试,另一个返回一个 $http 请求但不起作用。

我也尝试从服务中返回延迟并等待控制器响应,但没有成功,也许我做错了什么......有人可以帮助我吗?

我还制作了一个 plunker,以便您看到问题的实际效果......

http://plnkr.co/edit/7NIPeAsUYlh96p3hUij7

感谢您的宝贵时间... =)

【问题讨论】:

    标签: angularjs http asynchronous service controller


    【解决方案1】:

    幸好你创建了一个 plunker。

    问题出在服务的这个功能上:

    var data;
    var getAsyncData = function()
    {
        console.log(" -> getting data...");
        $http.get("menu.json")
        .success(function(result)
        {
            data = result;
    
            console.log("async data: " + data);
        });
    
         return data;
    }
    

    基本上你将一个未定义的变量返回给控制器,然后发出 http 请求,当你得到响应时你更新数据以引用结果,但控制器中的 $scope.menuList 仍然指向未定义(你'不更新函数返回的对象)。

    要修复它,您有 2 个选项:

    将视图绑定到您在服务中返回的对象的属性,然后在您从 http 调用获得响应时更新对象属性。 here's the relevant plunker

    其他选项是,对于服务中的异步调用,您返回一个承诺,一旦承诺解决,控制器可以使用请求的结果更新范围。 here's the relevant plunker

    【讨论】:

    • 谢谢!!! =D 这两种解决方案都适用于我的主要项目!我选择第一个。那样的话,我想我可以在服务内部有一个模型的概念并在那里更改数据,将控制器留给其他东西......
    【解决方案2】:

    我改变了一点我的服务...如果在另一个请求运行时发出另一个请求,则返回数据的引用,并且所有调用的人都将在完成后更新:

    module.factory("MainMenuService", ["$http", function ($http)
    {
        var isRequesting = false;
        var data = {};
    
        var getAsyncData = function()
        {
            if (isRequesting) return data;
    
            isRequesting = true;
    
            console.log(" -> getting async data...");
            $http.get("json/mainMenu.json")
            .success(function (result)
            {
                isRequesting = false;
    
                angular.forEach(result, function (value, key)
                {
                    value.id = key;
                    switch(value.submenus.length)
                    {
                        case 1: value.columnsSize = 12; break;
                        case 2: value.columnsSize = 6; break;
                        default: value.columnsSize = 4; break;
                    } 
                })
    
                data.menuList = result;
    
                console.log(" -> data.menuList : " + data.menuList);
            });
    
            return data;
        }
    
        return {
            GetAsyncData: function ()
            {
                return getAsyncData();
            }
        }
    }]);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-30
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      • 2016-09-04
      相关资源
      最近更新 更多