18

我试图让我的应用程序在更改路线之前收集数据,如 John Lindquist 的许多视频所示:http ://www.youtube.com/watch?v=P6KITGRQujQ&list=UUKW92i7iQFuNILqQOUOCrFw&index=4&feature=plcp

我已经把它全部连接起来了,但是当延迟对象解决的时候,我得到了错误:

Error: Argument 'fn' is not a function, got Object
at assertArg (http://localhost:9000/components/angular/angular.js:1019:11)
at assertArgFn (http://localhost:9000/components/angular/angular.js:1029:3)
at annotate (http://localhost:9000/components/angular/angular.js:2350:5)
at invoke (http://localhost:9000/components/angular/angular.js:2833:21)
at Object.instantiate (http://localhost:9000/components/angular/angular.js:2874:23)
at http://localhost:9000/components/angular/angular.js:4759:24
at <error: illegal access>
at Object.Scope.$broadcast (http://localhost:9000/components/angular/angular.js:8261:28)
at http://localhost:9000/components/angular/angular.js:7417:26
at wrappedCallback (http://localhost:9000/components/angular/angular.js:6797:59) angular.js:5704

我的代码如下所示:

路线 -

angular.module( 'saApp' )
.config( function ( $routeProvider, $locationProvider ) {
    $routeProvider
        .when( '/dashboard', {
            templateUrl: 'views/dashboard/dashboard.html',
            controller: Dashboard,
            resolve: Dashboard.resolve
        } 
});

控制器 -

var Dashboard = angular.module( 'saApp' ).controller(
    function ( $scope, dataset ) {
            $scope.data = dataset;
    } );

Dashboard.resolve = {
  dataset: function ( $q, DBFactory ) {

    console.log("dataset enter")
    var deferred = $q.defer();

    DBFactory.get( {noun: "dashboard"},
        function ( data ) {
            console.log("resolving");
            deferred.resolve( data );
        } );

    console.log("promise");
    return deferred.promise;
  }
}

运行时,它执行解析,DBFactory 资源去,回来,一切正常,直到实际的“deferred.resolve(data);” 这就是我在上面粘贴错误的地方。如果我评论那一行,当然我没有页面,但我也没有错误。

从 DBFactory 返回的数据内容是一个 JSON 对象,这是预期的,并且显示在我在网上和视频中看到的所有示例中。

使用:

AngularJS 1.0.6

想法?感谢你的帮助。

更新:

似乎我使用路由并使用命名空间定义控制器的方式:

var Dashboard = angular.module( 'saApp' ).controller()

应该为此负责。当我简单地使用标准函数声明时:

function DashboardCtrl($scope, dataset) {
  $scope.data = dataset;
}

它满足“寻找功能,得到对象”的错误。奇怪的是我将其更改为将其用作对象“var DashboardCtrl = angular.module('saApp').controller()”,甚至是我在 yeoman 生成器之前拥有的对象,并在 angularjs 文档中指定的:

angular.module( 'saApp' )
.controller( 'DashboardCtrl', function ( $scope, dataset ) {});

路线为:

.when( '/dashboard', {
            templateUrl: 'views/dashboard/dashboard.html',
            controller: 'DashboardCtrl'
        } )

行不通。

4

10 回答 10

8

我多次遇到此错误,终于找到了完美而简单的解决方案。只需将您的控制器名称放在“何时”构造中,如下所示:

.when( '/dashboard', {
    templateUrl: 'views/dashboard/dashboard.html',
    controller: 'Dashboard',
    resolve: Dashboard.resolve
}

代替

.when( '/dashboard', {
    templateUrl: 'views/dashboard/dashboard.html',
    controller: Dashboard,
    resolve: Dashboard.resolve
}
于 2013-12-26T22:16:45.747 回答
4

这将返回控制器对象:

var myCtrl = myApp.controller('whatever'...   

但是路由想要实际的控制器功能。所以....假设这是您的控制器并解决:(注意我将控制器命名为“IndexCtrl”...我认为您在代码中没有这样做)

myApp = angular.module('myApp')

var IndexCtrl = myApp.controller('IndexCtrl', function($scope){ 
   .. blah blah... 
})
IndexCtrl.resolve = {
  loadData:function(){ ... blah blah... }
}

您可以通过传入名称来有角度地查找控制器。(注意控制器引用是一个字符串)

.when('/',{controller:'IndexCtrl', resolve:IndexCtrl.resolve})
于 2013-05-23T04:53:38.487 回答
4

如果您在工厂中链接时不小心包含了额外的括号,也会发生这种情况:

坏的:

myModule.factory('monkey', ['$http', MonkeyFactory()]);

好的:

myModule.factory('monkey', ['$http', MonkeyFactory]);
于 2014-11-07T20:31:57.013 回答
2

或者如果您错误地在工厂/控制器名称之后进行了注入(错误的方式);

angular.module('MyModule')
    .factory('MyFactory', 'AnotherFactory', ['$http', function($http, AnotherFactory){
        // CODE HERE
    }]);

正确的方式;

angular.module('MyModule')
    .factory('MyFactory', ['$http', 'AnotherFactory', function($http, AnotherFactory){
        // CODE HERE
    }]);
于 2015-02-12T19:07:35.857 回答
2

我遇到过同样的问题。您可以通过执行以下操作来解决它。

从路由 .when() 方法中删除控制器声明。所以这...

.when( '/dashboard', {
        templateUrl: 'views/dashboard/dashboard.html',
        controller: Dashboard,
        resolve: Dashboard.resolve
    } 

变成了这个……

 .when( '/dashboard', {
        templateUrl: 'views/dashboard/dashboard.html',
        resolve: Dashboard.resolve
    } 

现在为了维护您的范围,在您的 html 模板中添加控制器声明。例如..

<div ng-controller="DashboardCtrl">{{Some fancy dashboard stuff}}</div>
于 2013-05-02T02:43:45.087 回答
2

当我忘记导出我正在导入的类时出现此错误

import MyService from './services/MyService'
app.service('MyService', MyService);

我的服务.js

class MyService(){
    // ... do stuff
}

需要是

export default class MyService(){
    // ... do stuff
}
于 2021-03-12T09:14:08.270 回答
2

在 Coffeescript 中使用 Karma 进行模块模拟时出现此错误。

解决方案是在 ($provide)-> 函数的末尾添加“return null”。没有它,coffeescript 将返回 $provide.value() 的结果,我猜它是一个对象,它以某种方式导致“'fn 不是函数”。

例子:

module 'myModule', ($provide)->
  $provide.value 'myInjectable',
    myFunction:-> return "dummy value"
  return null # prevents "fn is not a function"
于 2015-11-09T13:50:07.740 回答
2

我能够通过添加 {} 从另一个文件导入我的“函数”来解决这个“fn 不是函数,得到对象”,如下所示:

import {MenuCtrl} from './controllers/MenuCtrl.js';

老办法:

import MenuCtrl from './controllers/MenuCtrl.js';

引用了这个问题:https ://github.com/swimlane/angular-data-table/issues/189

于 2017-04-14T05:19:00.417 回答
1

如果您使用 Coffescript + angularjs,也会发生这种情况。

由于 angularjs 支持 Coffescript 类。

class IndexCtrl 
    constructor: () ->

myApp.controller('IndexCtrl',IndexCtrl)

然后在 .when()

“控制器:IndexCtrl”看到的是一个对象,而不是一个函数。

于 2015-01-02T03:21:33.367 回答
0

当我们在 html 中有一个未在控制器中定义的函数时,我们也会收到此错误。

于 2019-08-23T06:00:12.577 回答