繁体   English   中英

AngularJS应用一次为多个控制器加载和处理JSON数据

[英]AngularJS app loading and processing JSON data once for multiple controllers

我正在开发一个Angular应用程序,遇到了与本文大致相同的问题: AngularJS应用程序:一次从JSON加载数据并在多个控制器中使用

我有一个工厂,可以读取JSON文件,并返回整个数据对象。 然后,每个控制器都使用该工厂(作为服务?)来获取数据,但是每个控制器都必须自己将其拆开。 必须搜索和处理JSON以获取相关的有效负载,例如$scope.currentArray = data.someThing.allItems[i]; 等等,显然我不想在所有控制器中重复此代码。

在我看来,在MainController(“第一个”)完成工作后,我可以找到某种共享数据的方法, 或者可以在控制器和工厂之间“添加一些新模块”。 这个新模块-我们称它为myProcessService吗? -然后就是从工厂获取数据对象,并在那里一劳永逸地进行所有处理的人。 然后,每个控制器将只处理myProcessService以(以某种方式)将就绪格式的变量和数组等myProcessService其各自的作用域中(是的,这是Angular 1)。

如果我尝试举例说明到目前为止的操作方式,也许有人可以帮助我进行必要的改进? 而且,我知道今天就已经开始使用Angular 2模式是个好主意,但是请理解,在研究A2之前,我首先试图了解A1的工作原理:)

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


app.factory('getDataFile', ['$http', function($http) {
    function getStream(pid) {
        return $http.get("data/" + pid + ".json")
            .success(function(data) {
                    console.info("Found data for pid " + pid);
                    return data;
            })
            .error(function(err) {
                    console.error("Cant find data for pid " + pid);
                    return err;
            });
    }
    return {getStream: getStream};
}]);


app.controller('MainController', ['$scope', 'getDataFile', 
    function($scope, getDataFile) {     
        getDataFile.getStream('10101011').success(function(data) {

            // process "data" into what's relevant:
            var i = getRelevantIndexForToday(new Date());
            $scope.myVar = data.someField; 
            $scope.currentArray = data.someThing.allItems[i]; 
            // etc... you get the drift
        }
    }]);

app.controller('SecondController', ['$scope', 'getDataFile', 
    function($scope, getDataFile) {     
        getDataFile.getStream('10101011').success(function(data) {

            // process "data" into what's relevant:
            var i = getRelevantIndexForToday(new Date());
            $scope.myVar = data.someField; 
            $scope.currentArray = data.someThing.allItems[i]; 
            // etc... you get the drift
        }
    }]);

编辑:

我的ngRouter设置如下。 他们在我的index.html中填充了ng-view div。 但是-也许对此不满意? -我有一个“MainController”直接坐落在index.html的body标记,这样我可以显示单页应用程序的头部分的一些数据(从后端)。

app.config(function($routeProvider) {

  $routeProvider

  .when('/:id/work/:page_id', {
    controller: 'AssetController',
    templateUrl: 'app/views/work.html'
  })
  .when('/:id/work/', {
    redirectTo: '/:id/work/1'
  })
  .when('/:id/', {
    controller: 'DashController',
    templateUrl: 'app/views/dashboard.html'
  })
  .otherwise({
    redirectTo: '/'
  });

});

和index.html很像这样:

<body ng-app="myApp">

    <div class="container" ng-controller="MainController">

        <h1>Welcome, {{username}}</h1>

        <div ng-view></div>

    </div>
</body>

您可以在工厂中添加另一个帮助程序函数,该函数返回要在控制器之间共享的必需对象。

app.factory('getDataFile', ['$http', function($http) {
    function getStream(pid) {
        return $http.get("data/" + pid + ".json")
            .success(function(data) {
                    console.info("Found data for pid " + pid);
                    return data;
            })
            .error(function(err) {
                    console.error("Cant find data for pid " + pid);
                    return err;
            });
    }

    function getCurrent(pid) {
        return getStream(pid).then(function() {
                var i = getRelevantIndexForToday(new Date());

            return  {
                myVar: data.someField,
                currentArray: data.someThing.allItems[i];
            };
        });
    }

    return {
        getStream: getStream,
      getCurrent: getCurrent
    };
}]);

app.controller('MainController', ['$scope', 'getDataFile', 
    function($scope, getDataFile) {     
        getDataFile.getCurrent('10101011').success(function(data) {
            $scope.myVar = data.myVar; 
            $scope.currentArray = data.currentArray; 
            // etc... you get the drift
        }
    }]);

app.controller('SecondController', ['$scope', 'current', 
    function($scope, current) {     
        .success(function(data) {
                        $scope.myVar = data.myVar; 
            $scope.currentArray = data.currentArray;  
        }
    }]);

建议:

另外,我建议您使用resolve ,它允许您将数据从路由传递到控制器。

路线:

.when('/:id/work', {
    controller: 'AssetController',
    templateUrl: 'app/views/work.html',
     resolve: {
        // you are injecting current variable in the controller with the data. You can inject this to each of your controller. you dont need to add the whole function in your next route. Just use current
        current: function(getDataFile){
           return getDataFile.getCurrent('10101011');
        }
  })

控制器:

app.controller('MainController', ['$scope', 'current', 
    function($scope, current) {     
        $scope.myVar = current.myVar; 
        $scope.currentArray = current.currentArray;
    }]);

app.controller('SecondController', ['$scope', 'current', 
    function($scope, current) {     

        $scope.myVar = current.myVar; 
        $scope.currentArray = current.currentArray;  

    }]);

现在你有了

感谢您提供与我不赞成使用的方法successerror Subash一致的答案。 但是,您的答案中的代码有一些问题,我在#angularjs上获得了一些帮助,因此我认为我应该在此处发布更新的代码。

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

myApp.factory('getDataFile', ['$http', function($http) {
    function getStream(pid) {
        // here, using placeholder data URL, just to get some data:
        return $http.get('http://jsonplaceholder.typicode.com/users')
            .then(function(result) {
                    console.info("Found data for pid " + pid);
                    return result.data;
            })
            .catch(function(err) {
                    console.error("Cant find data for pid " + pid);
                    return err;
            });
    }

    function getCurrent(pid) {
        return getStream(pid).then(function(data) {
            var i = 1;  // test
            console.log("myVar = ", data[i].name);
            return  {
                myVar: data[i].name
            };
        });
    }

    return {
        getStream: getStream,
      getCurrent: getCurrent
    };
}]);

myApp.controller('MainController', ['$scope', 'getDataFile', 
    function($scope, getDataFile) {     
        $scope.name = "j";
        getDataFile.getCurrent('10101011').then(function(user) {
            $scope.myVar = user.myVar;

            console.log("controller. myVar = ", user);
            // etc... you get the drift
        });
    }]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM