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



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

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

在我看来,我可以找到某种方法来共享数据,例如,在 MainController("第一个")完成工作之后,或者我可以在控制器和工厂之间添加一些新模块。这个新模块 - 我们称之为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设置了这样的内容。它们填充了我的索引.html中的ng-viewdiv。然而 - 也许这是不受欢迎的?-- 我还有一个"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: '/'
  });
});

和索引.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
        });
    }]);

最新更新