Angularjs ng-controller有决心

Ras*_*lom 18 javascript angularjs

我遇到了ng-controller和'resolve'功能的问题:

我有一个控制器,需要在运行之前解决一些依赖关系,当我通过ng-route定义它时它工作正常:

控制器代码如下所示:

angular.module('myApp')
  .controller('MyController', ['$scope', 'data', function ($scope, data) {
      $scope.data = data;
    }
  ]
);
Run Code Online (Sandbox Code Playgroud)

路由:

...
.when('/someUrl', {
        templateUrl : 'some.html',
        controller : 'MyController',
        resolve : {
          data: ['Service', function (Service) {
            return Service.getData();
          }]
        }
})
...
Run Code Online (Sandbox Code Playgroud)

当我去/ someUrl时,一切正常.

但是我需要以其他方式使用这个控制器(我需要在不同的地方使用这两种方式):

<div ng-controller="MyController">*some html here*</div>
Run Code Online (Sandbox Code Playgroud)

当然,它失败了,因为"数据"依赖性没有得到解决.当我使用'ng-controller'或者我应该放弃并在控制器中加载数据时,有没有办法将依赖注入控制器?

JcT*_*JcT 11

在下面,对于路由解析,我们正在解析promise并将返回数据包装在具有属性的对象中.然后,我们在用于ng-controller表单的包装器服务('dataService')中复制此结构.

包装器服务也解析了promise,但是在内部执行,并更新了我们已经返回的对象的属性以供控制器使用.

在控制器中,如果您希望延迟一些其他行为,直到所有内容都解决并且数据可用后,您可能会在此属性上放置一个观察程序.

或者,我演示了使用"包裹"另一个控制器的控制器; 一旦解决了Service的承诺,它就会将自己的$ scope传递给包装的控制器以及Service中现在解析的数据.

请注意,我已经使用$ timeout来为promise返回提供1000ms的延迟,试着让它更清楚地发生了什么以及什么时候发生.

angular.module('myApp', ['ngRoute'])
  .config(function($routeProvider) {
    $routeProvider
      .when('/', {
        template: '<h1>{{title}}</h1><p>{{blurb}}</p><div ng-controller="ResolveController">Using ng-controller: <strong>{{data.data}}</strong></div>',
        controller: 'HomeController'
      })
      .when('/byResolve', {
        template: '<h1>{{title}}</h1><p>{{blurb}}</p><p>Resolved: <strong>{{data.data}}</strong></p>',
        controller: "ResolveController",
        resolve: {
          dataService: ['Service',
            function(Service) {
              // Here getData() returns a promise, so we can use .then.
              // I'm wrapping the result in an object with property 'data', so we're returning an object
              // which can be referenced, rather than a string which would only be by value.
              // This mirrors what we return from dataService (which wraps Service), making it interchangeable.
              return Service.getData().then(function(result) {
                return {
                  data: result
                };
              });
            }
          ]
        }
      })
      .when('/byWrapperController', {
        template: '<h1>Wrapped: {{title}}</h1><p>{{blurb}}</p><div ng-controller="WrapperController">Resolving and passing to a wrapper controller: <strong>{{data.data ? data.data : "Loading..."}}</strong></div>',
        controller: 'WrapperController'
      });
  })
  .controller('HomeController', function($scope) {
    $scope.title = "ng-controller";
    $scope.blurb = "Click 'By Resolve' above to trigger the next route and resolve.";
  })
  .controller('ResolveController', ['$scope', 'dataService',
    function($scope, dataService) {
      $scope.title = "Router and resolve";
      $scope.blurb = "Click 'By ng-controller' above to trigger the original route and test ng-controller and the wrapper service, 'dataService'.";
      $scope.data = dataService;
    }
  ])
  .controller('WrapperController', ['$scope', '$controller', 'Service',
    function($scope, $controller, Service) {
      $scope.title = "Resolving..."; //this controller could of course not show anything until after the resolve, but demo purposes...
      Service.getData().then(function(result) {
        $controller('ResolveController', {
          $scope: $scope, //passing the same scope on through
          dataService: {
            data: result
          }
        });
      });
    }
  ])
  .service('Service', ['$timeout',
    function($timeout) {
      return {
        getData: function() {
          //return a test promise
          return $timeout(function() {
            return "Data from Service!";
          }, 1000);
        }
      };
    }
  ])
  // our wrapper service, that will resolve the promise internally and update a property on an object we can return (by reference)
  .service('dataService', function(Service) {
    // creating a return object with a data property, matching the structure we return from the router resolve
    var _result = {
      data: null
    };
    Service.getData().then(function(result) {
      _result.data = result;
      return result;
    });
    return _result;
  });
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.27/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.27/angular-route.min.js"></script>
<div ng-app="myApp">
  <a href="#/">By ng-controller</a> |
  <a href="#/byResolve">By Resolve</a> |
  <a href="#/byWrapperController">By Wrapper Controller</a>
  <div ng-view />
</div>
Run Code Online (Sandbox Code Playgroud)


小智 3

创建一个新模块,在其中注入要注入的服务,如下所示。

var module = angular.module('myservice', []);

module.service('userService', function(Service){
    return Service.getData();
});
Run Code Online (Sandbox Code Playgroud)

将新创建的服务模块注入您的应用程序模块中

angular.module('myApp')
  .controller('MyController', ['$scope', 'myservice', function ($scope, myservice) {
      $scope.data = data;
    // now you can use new dependent service anywhere here.
    }
  ]
);
Run Code Online (Sandbox Code Playgroud)