AngularJS使用字符串作为控制器来解析

10 浏览
0 Comments

AngularJS使用字符串作为控制器来解析

我写Angular控制器的风格是这样的(使用控制器名称而不是函数):\n

angular.module('mymodule', [])
    .controller('myController', ['$scope', function($scope) {
        // 这里是一些代码
    }]);

\n现在我需要在提供路由时定义resolve部分:\n

$routeProvider.when('/someroute', {
    templateUrl: 'partials/someroute.html', 
    resolve: myController.resolve}) // 这是关键的一行

\n由于控制器被定义为一个名称,如何完成下面的resolve部分?\n更详细地说明,我想在路由解析之前从服务器加载一些数据,然后在控制器中使用这些数据。\n更新:更准确地说,我希望每个模块都有一个\"resolve\"函数,在执行具有该控制器的路由之前调用该函数。在这个帖子中的解决方案(由Misko Hevery回答)正是我想要的,但我不是将控制器作为函数而是作为名称。

0
0 Comments

在AngularJS中,可以使用resolve属性来定义在控制器加载之前需要解析的依赖项。通常,resolve属性的值是一个对象,其中的键是依赖项的名称,值是一个函数或一个数组。如果值是一个函数,它应该返回一个promise对象。如果值是一个数组,数组的最后一个元素应该是一个函数,它应该返回一个promise对象。resolve属性可以用来确保在控制器加载之前,所有的依赖项都被解析和注入。

然而,在某些情况下,当控制器以字符串的形式传递给AngularJS的controller方法时,resolve属性不起作用。这是因为当控制器以字符串形式传递时,AngularJS无法获取控制器的实例,因此无法将resolve属性的值与控制器实例相关联。

解决这个问题的方法是将控制器定义为一个变量,并将resolve属性添加到该变量上。然后,使用controller方法将该变量传递给AngularJS。这样,AngularJS就能够正确地解析resolve属性,并在控制器加载之前解析和注入所有的依赖项。

以下是正确使用resolve属性的示例代码:

var MyController = myApp.controller('MyController', ['$scope', 'myData', function($scope, myData) {
  // Some code here
}]);
MyController.resolve = {
  myData: ['$http', '$q', function($http, $q) {
    var defer = $q.defer();
    $http.get('/foo/bar')
      .success(function(data) {
        defer.resolve(data);
      })
      .error(function(error, status) {
        defer.reject(error);
      });
    return defer.promise;
  }]
};

在上面的代码中,我们首先定义了一个变量MyController,并将其设置为myApp.controller方法的返回值。然后,我们将resolve属性添加到MyController上,并定义了一个名为myData的依赖项。myData依赖项使用$http服务来获取数据,并返回一个promise对象。

最后,我们使用controller方法将MyController作为字符串传递给AngularJS。由于MyController是一个变量,而不是一个字符串,AngularJS能够正确地解析resolve属性,并在控制器加载之前解析和注入myData依赖项。

通过这种方式,我们可以确保在控制器加载之前,myData依赖项已经被解析和注入,从而避免了resolve属性不起作用的问题。

0
0 Comments

问题出现的原因是想要在AngularJS中使用resolve和controller作为字符串,而不是函数。解决方法是在路由文件中添加resolve属性,并将controller和resolve的值都作为字符串放入数组中。

首先,在模块中定义控制器和工厂函数,其中工厂函数返回一个promise。然后在控制器中使用resolved的工厂函数。代码如下:

angular.module('mymodule', [])
  .controller('myController', ['$scope', 'myModelCombination', function($scope, myModelCombination) {
      // myModelCombination[0] === (resolved) myModel 
      // myModelCombination[1] === (resolved) myModel2
  }])
  .controller('myController2', ['$scope', 'myModel', function($scope, myModel) {
      // Some code here
  }])
  .factory('myModel', ['$scope', function($scope) {
      // return a promise
  }])
  .factory('myModel2', ['$scope', function($scope) {
      // return a promise
  }])
  .factory('myModelCombination', ['$scope', 'myModel', 'myModel2', function($scope) {
      return $q.all(['myModel', 'myModel2']);
  }]);

然后在路由文件中添加resolve属性,并将controller和resolve的值都作为字符串放入数组中。代码如下:

$routeProvider.when('/someroute', {
    templateUrl: 'partials/someroute.html', 
    resolve: ['myModel'] //ALWAYS IN ARRAY)
});
$routeProvider.when('/myModelCombination', {
    templateUrl: 'partials/someroute2.html', 
    resolve: ['myModel'] //ALWAYS IN ARRAY)
});

最后,确保每个工厂函数只返回一个值或一个promise,除非希望等待所有promise完成并将它们一起返回。需要注意的是,工厂函数的返回值应该是一个promise。代码如下:

.factory('myModel', ['$scope', function($scope) {
    // return a promise
}])

这样就可以在AngularJS中使用resolve和controller作为字符串了。详细的API文档可以参考http://docs.angularjs.org/api/ng.$routeProvider。

如果有多个promise需要返回,可以使用$q.all()方法将它们一起返回。代码如下:

.factory('myModelCombination', ['$scope', 'myModel', 'myModel2', function($scope) {
    return $q.all(['myModel', 'myModel2']);
}]);

如果以上方法不起作用,可以尝试在fiddle中运行代码来进行调试。

0
0 Comments

AngularJS中,控制器定义和解析部分需要分别在路由定义中指定。

如果在模块级别上定义控制器,需要将它们作为字符串引用,如下所示:

$routeProvider.when('/someroute', {
        templateUrl: 'partials/someroute.html', 
        controller: 'myController',
        resolve: {
          myVar: function(){
            //在路由变化之前执行的代码
          };
        });

上面的代码还展示了如何定义一组在路由变化之前将被解析的变量。当这些变量被解析后,可以将它们注入到控制器中。所以根据上面的代码片段,你可以这样编写控制器:

.controller('myController', ['$scope', 'myVar', function($scope, myVar) {
            // myVar已经被解析并注入到这里
        }
    ]);

这个视频也可能会有帮助:http://www.youtube.com/watch?v=P6KITGRQujQ

你可以将服务注入到控制器和解析函数中,如果这是你的问题的话...你能更具体一些吗?

在when()内部,'myController',应该是controller: 'myController',吗?

确实是这样的。已经修复了。

.opensource当我为路由的controller属性提供一个字符串时,我会得到一个关于myVarProvider未知的错误。有什么想法吗?

你使用的是哪个版本?

在这种情况下,resolve键的确切含义是什么?在这个例子中是"myVar"吗?

当我为路由的controller属性提供一个字符串时,我也会遇到"provider unknown"的错误。然而,如果我使用一个函数,那么resolve属性就能成功注入,并且一切都很顺利。

我刚刚遇到了同样的问题,并在这里找到了答案:groups.google.com/forum/#!topic/angular/6nA4MEKyKAc。基本上,我还需要从我的视图中删除ng-controller,并让路由添加它以及解析后的数据。

太棒了,我不知道我可以直接从路由的解析部分将变量注入到控制器中,我一直在使用$route['current']['locals']来获取解析定义中的变量。

.opensource是否可以在解析中添加多个控制器,例如: controller: 'myController', 'secondController, thirdController

AngularJS中的一个常见问题是在使用控制器字符串进行解析时出现错误。通常,在路由定义中,控制器定义和解析部分需要分别指定。如果在模块级别上定义控制器,需要将它们作为字符串引用。下面是一个示例的代码片段:

$routeProvider.when('/someroute', {
    templateUrl: 'partials/someroute.html', 
    controller: 'myController',
    resolve: {
        myVar: function(){
            //在路由变化之前执行的代码
        };
    });

上面的代码中,定义了一个将在路由变化之前解析的变量myVar。当这些变量被解析后,可以将它们注入到控制器中。以下是控制器的示例代码:

.controller('myController', ['$scope', 'myVar', function($scope, myVar) {
    // myVar已经被解析并注入到这里
}]);

通过这种方式,可以在控制器中使用解析后的变量。同时,还可以将服务注入到控制器和解析函数中。

此外,有一个视频也可以帮助解决这个问题。如果需要注入多个控制器,在解析部分可以添加多个控制器的引用。

如果使用控制器字符串进行解析时出现问题,可能是因为在路由定义中使用了错误的语法。可以参考相关文档或寻求社区的帮助来解决这个问题。

参考链接:

- http://www.youtube.com/watch?v=P6KITGRQujQ

- groups.google.com/forum/#!topic/angular/6nA4MEKyKAc

0