Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS函数可用于多个控制器_Javascript_Angularjs - Fatal编程技术网

Javascript AngularJS函数可用于多个控制器

Javascript AngularJS函数可用于多个控制器,javascript,angularjs,Javascript,Angularjs,在AngularJS+RestAPI中构建一个简单的控制面板 构建了一个简单的工厂,用于发出API请求(GET,POST),并向成功回调返回必要的数据。需要处理返回数据并更改$scope,因为API可能返回服务器端表单字段错误 我无法在工厂内构建处理/更改$scope,因为工厂没有(也不应该)访问该范围。我不希望在成功回调中处理/应用,因为它是重复的(每个API请求一次) 解决这个问题的最佳“角度方法”是什么 一种可能的解决方案是在角度应用程序之外存在一个函数,然后只需将$scope和必要的数据

AngularJS+RestAPI中构建一个简单的控制面板

构建了一个简单的工厂,用于发出API请求
(GET,POST)
,并向成功回调返回必要的数据。需要处理返回数据并更改
$scope
,因为API可能返回服务器端表单字段错误

我无法在工厂内构建处理/更改
$scope
,因为工厂没有(也不应该)访问该范围。我不希望在成功回调中处理/应用,因为它是重复的(每个API请求一次)

解决这个问题的最佳“角度方法”是什么

一种可能的解决方案是在角度应用程序之外存在一个函数,然后只需将$scope和必要的数据传递给它。

这感觉像是一个糟糕的工作环境(见下文)


为什么不在控制器中包含一个函数来处理它呢?我通常是这样处理的:

myApp.controller("saveForm", ["$scope", "api", function($scope, api), function() {
    ...
    $scope.submit = function() {
        api("POST", url, $scope.data, function(data) {
            //onSuccess
            processData(data);
        });
    }
    function provessData(data){
        // do stuff to data
        $scope.foo = data;
    }
    ...
}]);

您的控制器似乎做了太多的工作,并且对实际请求(url、“POST”方法等)了解太多

如何将工厂中的数据转换为控制器期望的数据。工厂不需要知道任何关于范围的事情。它只是将数据转换成控制器可以使用的格式,然后将其发送回。这样,工厂可以跨控制器重用

myApp.controller("saveForm", ["$scope", "api", function($scope, api), function() {
    ...
    $scope.submit = function() {

// Call API.update and handle the deferred that is returned, which will be the transformed data
        api.update($scope.data).then(function (transformedData) {
           scope....

        });
    }
    ...
}]);

myApp.factory('api', ['$http', '$q', function($http, $q) {
    return {
         update : function () {

             var deferred = $q.defer();

             $http({
               method: "GET",
               url: "your/url/path"

             }).success(function(data) {

                var transformedData;

                // Perform data transformation here instead of in controllers
                angular.forEach(data, function (value, key) {
                    transformedData.....
                });

                deferred.resolve(transformedData);
             });

             return deferred.promise;
         }
    }
}]);

不确定我是否理解您,但您可以通过mixin方式扩展控制器:

基本控制器

(function() {
  'use strict';

  angular.module('Base', []);

  function BaseController($scope, <injectables>, that) {
    that.mixin1 = function() {
    };

    that.mixin2 = function(arg1, arg2) {
    };
  }

  angular.module('Base').controller('BaseController',
    ['$scope', '...', BaseController]);
})();
(function() {
  'use strict';

  angular.module('Derived', ['Base']);

  function DerivedController($scope, $controller, ...) {
    $controller('BaseController', {
      '$scope' : $scope,
      ...
      'that' : this
    });

    // this.mixin1
    // this.mixin2
  }

  angular.module('Derived').controller('DerivedController',
    ['$scope', '$controller', '...', DerivedController]);
})();

请注意,您可以使用Angular的
$controller
服务来混合功能。

您可以创建一个工厂,返回您的
processData
功能:

myApp.factory('processData', [function () {
    return function(scope, data) {
        angular.forEach(data, function(value, key)) {
            scope....
        }
    };
}]);
然后通过角度注射:

myApp.controller("saveForm", ["$scope", "api", "processData", function($scope, api, processData) {
    ...
    $scope.submit = function() {
        api("POST", url, $scope.data, function(data) {
            //onSuccess
            processData($scope, data);
        });
    }
    ...
}]);

与在DI之外声明函数相比,这种方法的优点是,如果需要,仍然可以在单元测试中轻松模拟
processData
依赖关系。

这确实有效,但是,我有多个控制器需要使用processData()。在这个实现中,我必须在每个控制器中包含函数;重复的代码。然后试试这个:好吧,那么在这种情况下,你会推荐我给出的解决方案,但感觉很混乱,因为它存在于Angular应用程序之外。此外,我认为控制器应该更通用、更具体数据、更不具体功能。您可能需要处理所有表单数据的通用表单控制器,以及处理表单功能的表单指令,而不是存储表单控制器。为什么有多个控制器处理相同的数据?我绝对不建议从角度来处理函数。在Angular中有处理util函数的解决方案。madhead的解决方案正是您当时所寻找的。创建一个base/util控制器,并将其注入到需要的地方。这确实有效,但并不能解决问题。我有多个控制器使用
api
工厂,以相同的方式处理数据并更改$scope。将它放在每个成功回调中会导致大量重复代码。
myApp.controller("saveForm", ["$scope", "api", "processData", function($scope, api, processData) {
    ...
    $scope.submit = function() {
        api("POST", url, $scope.data, function(data) {
            //onSuccess
            processData($scope, data);
        });
    }
    ...
}]);