【问题标题】:TypeError: undefined is not a function in Angular ResourceTypeError: undefined is not a function in Angular Resource
【发布时间】:2014-06-29 19:45:34
【问题描述】:

当尝试在 AngularJS 资源上轮询自定义方法 copies 时,我在 angular.js:10033 收到以下错误:(方法 copy 工作正常。)

TypeError: undefined is not a function
at https://code.angularjs.org/1.3.0-beta.8/angular-resource.min.js:9:347
at Array.forEach (native)
at q (https://code.angularjs.org/1.3.0-beta.8/angular.min.js:7:280)
at q.then.p.$resolved (https://code.angularjs.org/1.3.0-beta.8/angular-resource.min.js:9:329)
at J (https://code.angularjs.org/1.3.0-beta.8/angular.min.js:101:5)
at J (https://code.angularjs.org/1.3.0-beta.8/angular.min.js:101:5)
at https://code.angularjs.org/1.3.0-beta.8/angular.min.js:102:173
at g.$eval (https://code.angularjs.org/1.3.0-beta.8/angular.min.js:113:138)
at g.$digest (https://code.angularjs.org/1.3.0-beta.8/angular.min.js:110:215)
at g.$apply (https://code.angularjs.org/1.3.0-beta.8/angular.min.js:113:468)

Angular.js 10016 - 10035:

function consoleLog(type) {
  var console = $window.console || {},
      logFn = console[type] || console.log || noop,
      hasApply = false;

  // Note: reading logFn.apply throws an error in IE11 in IE8 document mode.
  // The reason behind this is that console.log has type "object" in IE8...
  try {
    hasApply = !!logFn.apply;
  } catch (e) {}

  if (hasApply) {
    return function() {
      var args = [];
      forEach(arguments, function(arg) {
        args.push(formatError(arg));
      });
      return logFn.apply(console, args); // This is line 10033 where the error gets thrown.
    };
  }

简化资源:

angular.module('vgm.content-pages')
.factory('ContentPage', function($resource, $http) {

  return $resource('/api/content-page/:id', { id:'@page.id' }, {
    copy: {
      method: 'POST',
      url: '/api/content-page/copy/:id'
    },
    copies: {
      method: 'GET',
      isArray: true,
      url: '/api/content-page/copies/:id'
    }
  });

});

我收到错误的简化指令:

angular.module('vgm.genericForms')
.directive('vgmFormCopyPicker', function() {

  return {
    restrict: 'E',
    replace: true,
    templateUrl: '/static/common/generic-forms/widgets/view-copy-picker.html',
    scope: {
      resource: '=',
    },
    controller: function($scope, $element) {

      $scope.pages = [];

      $scope.loadCopies = function() {

        $scope.resource.$copies()
          .then(function(response) {
            $scope.pages = response.data;
          });

      };

    }
  };

});

只要我运行loadCopies 方法,执行$scope.resource.$copies() 行就会抛出上述错误。

在 Chrome Inspector 中,我看到对我的 API 的调用实际上正在完成。但是解决承诺似乎会引发一些错误......

我该如何解决这个错误?

编辑:

$scope.resource = ContentPage.get({id: $stateParams.id}).$promise
$scope.resource.$save() // Works
$scope.resource.$update() // Works
$scope.resource.$copy() // Works
$scope.resource.$copies() // Does not work!

Angular Resource 正在尝试用一组项目覆盖我的初始资源。但是Resource的实例当然没有push的方法。

【问题讨论】:

    标签: javascript angularjs angularjs-directive angularjs-scope angularjs-resource


    【解决方案1】:

    我找到了答案:

    资源应该在其剩余生命周期内代表匹配的数据对象。如果你想获取新数据,你应该使用一个新对象。

    $scope.copies = ContentPage.copies()
    

    【讨论】:

    • 谢谢吉多。我有同样的问题。我认为文档有点混乱。如果我理解正确,您不能在 /single/ 资源实例上调用具有 isArray:true 的实例方法,因为单个实例不是数组。
    • 没错。仔细想想,它是有道理的:首先该属性表示一个项目列表,然后突然它表示一个项目,这是不一致的。
    【解决方案2】:

    Guido 的答案是正确的,但我第一次没有得到它。

    如果您将自定义方法添加到您的 Angular $resource 并使用 isArray: true 并期望从您的 WebService 中获取一些东西的数组,您可能希望将响应存储在一个数组中。

    因此你不应该像这样使用实例方法:

    var ap = new Ansprechpartner();
    $scope.nameDuplicates = ap.$searchByName(...);
    

    但是直接使用资源:

    $scope.nameDuplicates = Ansprechpartner.searchByName(...)
    

    使用以下 Angular 资源:

    mod.factory('Ansprechpartner', ['$resource',
        function ($resource) {
            return $resource('/api/Ansprechpartner/:id', 
                { id: '@ID' },
                {
                    "update": { method: "PUT" },
                    "searchByName": { method: "GET", url: "/api/Ansprechpartner/searchByName/:name", isArray: true }
                }
            );
        }
    ]);
    

    【讨论】:

      【解决方案3】:

      我正在使用Mean.js,这困扰了几个小时。有一个内置的$update,但是当我尝试将它应用于$resource 返回的对象时它不起作用。为了让它工作,我必须改变调用资源的方式来更新它。

      例如,对于Student 模块,我将它与$resource 一起返回到$scope.student。当我尝试更新 student.$update 时返回此错误。通过将调用修改为Students.update(),它解决了问题。

       $scope.update = function() {
         var student = $scope.student;
         var result = Students.update(student);
      
         if(result){
            $scope.message = 'Success';
         } else {
            $scope.error = 
              'Sorry, something went wrong.';
         }
       };

      【讨论】:

        猜你喜欢
        • 2021-11-12
        • 2015-09-18
        • 2013-12-22
        • 2015-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多