Простой тест разрешения Angular $ routeProvider. Что не так с этим кодом?

Я создал простое тестовое приложение Angular JS $routeProvider. Это дает следующую ошибку:

Error: Unknown provider: dataProvider <- data

Я был бы признателен, если бы кто-нибудь мог определить, где я ошибся.

index.html

<!DOCTYPE html>
<html ng-app="ResolveTest">
  <head>
    <title>Resolve Test</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js">    </script>
    <script src="ResolveTest.js"></script>
  </head>
  <body ng-controller="ResolveCtrl">
    <div ng-view></div>
  </body>
</html>

ResolveTest.js

var rt = angular.module("ResolveTest",[]);

rt.config(["$routeProvider",function($routeProvider)
{
  $routeProvider.when("/",{
    templateUrl: "rt.html",
    controller: "ResolveCtrl",
    resolve: {
      data: ["$q","$timeout",function($q,$timeout)
      {
        var deferred = $q.defer();

        $timeout(function()
        {
          deferred.resolve("my data value");
        },2000);

        return deferred.promise;
      }]
    }
  });
}]);

rt.controller("ResolveCtrl",["$scope","data",function($scope,data)
{
  console.log("data : " + data);
  $scope.data = data;
}]);

rt.html

<span>{{data}}</span>



Ответы (3)


Проблема в том, что у вас есть ng-controller="ResolveCtrl" в теге body в index.html, хотя в $routeProvider вы указываете тот же контроллер для rt.html. Выньте определение контроллера из вашего тега body и просто позвольте $routeProvider позаботиться об этом. После этого отлично работает.

person John Woodruff    schedule 31.05.2013
comment
robbymurphy - у вас нет ни решения, ни инъекции результата в вашу скрипку, поэтому вы неправильно воспроизводите проблему. - person Hilo; 31.05.2013
comment
@CM, вы правы, у меня сложилось впечатление, что вы утверждали, что у вас не может быть контроллер, указанный как в маршруте, так и в разметке. - person robbymurphy; 31.05.2013

Согласно документации angularjs для $routeprovider, объект разрешения представляет собой карту из ключа (зависимость name) в фабричную функцию или имя существующей службы. Попробуйте это вместо этого:

var myFactory = function($q, $timeout) { ... };
myFactory.$inject = ['$q', '$timeout'];

$routeProvider.when("/",{
    templateUrl: "rt.html",
    controller: "ResolveCtrl",
    resolve: {
      data: myFactory
    }
});
person robbymurphy    schedule 31.05.2013
comment
Из документа AngularJS $routeProvider для решения: factory - {строка | функция}: если строка, то это псевдоним для службы. В противном случае, если функция, то она вводится, а возвращаемое значение рассматривается как зависимость. Если результатом является обещание, оно разрешается до того, как его значение будет введено в контроллер. - person Hilo; 31.05.2013

Добавляя данные в определение контроллера, вы сообщаете angular, что ожидаете внедрить здесь службу или фабрику, но у вас нет службы данных или фабрики, поэтому возникает ошибка. Для использования переменной данных у вас есть все необходимое из строки $scope.data. Поэтому, чтобы исправить это, вам нужно удалить инъекцию данных из вызова вашего контроллера.

var rt = angular.module("ResolveTest",[]);

rt.config(["$routeProvider",function($routeProvider)
{
  $routeProvider.when("/",{
    templateUrl: "rt.html",
    controller: "ResolveCtrl",
    resolve: {
      data: ["$q","$timeout",function($q,$timeout)
      {
        var deferred = $q.defer();

        $timeout(function()
        {
          deferred.resolve("my data value");
        },2000);

        return deferred.promise;
      }]
    }
  });
}]);

rt.controller("ResolveCtrl",["$scope", function($scope)
{
  $scope.data = "";
}]);

Если вы хотите, чтобы поставщик данных добавил фабрику, например

rt.factory('data', ['$http', function($http){
 return {
   // Functions to get data here
 }
}]);

Затем в вашем контроллере вызовите соответствующую функцию из этой фабрики.

Кроме того, как указывали другие, вам не нужен контроллер как на вашем маршруте, так и в ng-контроллере (это будет вкладывать ваш контроллер в ваш контроллер, если вы проверите области).

Если вы должны использовать разрешение, вам все равно нужна фабрика, так как разрешение просто укажет на правильную фабрику, которую необходимо объявить отдельно.

person Paul Ryan    schedule 31.05.2013
comment
Если resolve — это функция, возвращающая обещание, она разрешается, а затем внедряется в контроллер. - person Hilo; 31.05.2013