Angularjs NG-控制器决心 [英] Angularjs ng-controller with resolve

查看:112
本文介绍了Angularjs NG-控制器决心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我跑进与NG-控制器和解析功能的问题:

我有一些需要依赖运行之前必须解决一个控制器,它工作正常,当我通过NG路由定义它:

控制器code是这样的:

  angular.module('对myApp')
  .controller('myController的',['$范围','数据',函数($范围,数据){
      $ scope.data =数据;
    }
  ]
);

路由:

  ...
。当('/ someUrl',{
        templateUrl:some.html',
        控制器:'myController的,
        解析:{
          数据:['服务',函数(服务){
            返回Service.getData();
          }]
        }
})
...

当我去/ someUrl,一切正常。

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

 < D​​IV NG控制器=myController的> *一些HTML这里* LT; / DIV>

和,当然,它失败了,因为数据的依赖并没有得到解决。有什么办法,当我使用'NG控制器或者我应该放弃和加载数据的内部控制器依赖注入到控制器?


解决方案

在下面,对于路线的决心,我们要解决的承诺,并与一个属性的对象包装返回数据。然后,我们重复在包装服务('的DataService'),我们使用了NG-控制器形式的这种结构。

该包装服务还解决了希望,但是这样做在内部,并在对象上更新属性我们已经回到了由控制器消耗。

在控制器,你很可能把一个观察者对这个属性,如果你想拖延一些额外的行为,直到一切都解决后,数据是可用的。

另外,我使用的是控制器'包装'另一个控制器证明;一旦从服务承诺得到解决,它就会传递到包装控制器,以及从服务现已解决了数据自己的$范围。

请注意,我用$超时提供的承诺回报1000毫秒的延迟,开始尝试做多一点清楚发生了什么时候。

\r
\r

angular.module('对myApp',['ngRoute'])\r
  的.config(函数($ routeProvider){\r
    $ routeProvider\r
      。什么时候('/', {\r
        模板:'< H1>的{{title}}< / H1>< P> {{导语}}< / P>< D​​IV NG控制器=ResolveController>使用NG控制器:其中;强> {{}数据。数据}< / STRONG>< / DIV>,\r
        控制器:HomeController的\r
      })\r
      。当('/ byResolve',{\r
        模板:'< H1>的{{title}}< / H1>< P> {{导语}}< / P>< P>解决:其中;强> {{数据。数据}}< / STRONG>< / p>,\r
        控制器:ResolveController\r
        解析:{\r
          DataService的:服务,\r
            功能(服务){\r
              //这里的getData()返回一个承诺,所以我们可以使用。于是。\r
              //我包裹在财产'数据'的对象的结果,所以我们返回一个对象\r
              //它可以被引用,而不是字符串这将只能由值。\r
              //这反映了我们从DataService的(它封装服务)返回,使其互换。\r
              返回Service.getData()。然后(功能(结果){\r
                返回{\r
                  数据:结果\r
                };\r
              });\r
            }\r
          ]\r
        }\r
      })\r
      。当('/ byWrapperController',{\r
        模板:'< H1>裹:{{title}}的< / H1>< P> {{导语}}< / P>< D​​IV NG控制器=WrapperController>解决并传递到包装控制器:其中;强> {{数据。数据?数据。数据:正在加载...}}< / STRONG>< / DIV>,\r
        控制器:'WrapperController\r
      });\r
  })\r
  .controller(HomeController中',函数($范围){\r
    $ scope.title =NG控制器;\r
    $ scope.blurb =点击通过解决上述触发下一个路线和解决。\r
  })\r
  .controller('ResolveController',['$范围,DataService的,\r
    功能($范围的DataService){\r
      $ scope.title =路由器和解决;\r
      $ scope.blurb =点击吴控制器上述触发原来的路线和测试NG-控制器和包装服务,DataService的'。\r
      $ scope.data = DataService的;\r
    }\r
  ])\r
  .controller('WrapperController',['$范围,$控制器,服务,\r
    功能($范围,$控制器,服务){\r
      $ scope.title =解决......; //这个控制器当然可以不显示任何东西,直到决心之后,却演示的目的...\r
      Service.getData()。然后(功能(结果){\r
        $控制器('ResolveController',{\r
          $范围:$范围,//传递通过相同的范围\r
          DataService的:{\r
            数据:结果\r
          }\r
        });\r
      });\r
    }\r
  ])\r
  。服务('服务',['$超时',\r
    功能($超时){\r
      返回{\r
        的getData:功能(){\r
          //返回测试的承诺\r
          返回$超时(函数(){\r
            从服务数据!返回;\r
          },1000);\r
        }\r
      };\r
    }\r
  ])\r
  //我们的包装服务,将内部解决的承诺和更新性质的物体上,我们可以返回(引用)\r
  。服务('的DataService',函数(服务){\r
    //创建带有数据属性返回对象,匹配结构,我们从路由器决心返回\r
    VAR _result = {\r
      数据:空\r
    };\r
    Service.getData()。然后(功能(结果){\r
      _result.data =结果;\r
      返回结果;\r
    });\r
    返回_result;\r
  });

\r

&LT;脚本SRC =htt​​ps://ajax.googleapis.com/ajax /libs/angularjs/1.2.27/angular.min.js\"></script>\r
&所述; SCRIPT SRC =htt​​ps://ajax.googleapis.com/ajax/libs/angularjs/1.2.27/angular-route.min.js&GT;&下; /脚本&GT;\r
&LT; D​​IV NG-应用=对myApp&GT;\r
  &LT; A HREF =#/&GT;吴控制器&LT; / A&GT; |\r
  &LT; A HREF =#/ byResolve&GT;通过以下方法解决:LT; / A&GT; |\r
  &LT; A HREF =#/ byWrapperController&GT;通过包装控制器&LT; / A&GT;\r
  &LT; D​​IV NG画面/&GT;\r
&LT; / DIV&GT;

\r

\r
\r

I've ran into problem with ng-controller and 'resolve' functionality:

I have a controller that requires some dependency to be resolved before running, it works fine when I define it via ng-route:

Controller code looks like this:

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

Routing:

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

when I go to /someUrl, everything works.

But I need to use this controller in other way(I need both ways in different places):

<div ng-controller="MyController">*some html here*</div>

And, of course, it fails, because 'data' dependency wasn't resolved. Is there any way to inject dependency into controller when I use 'ng-controller' or I should give up and load data inside controller?

解决方案

In the below, for the route resolve, we're resolving the promise and wrapping the return data in an object with a property. We then duplicate this structure in the wrapper service ('dataService') that we use for the ng-controller form.

The wrapper service also resolves the promise but does so internally, and updates a property on the object we've already returned to be consumed by the controller.

In the controller, you could probably put a watcher on this property if you wanted to delay some additional behaviours until after everything was resolved and the data was available.

Alternatively, I've demonstrated using a controller that 'wraps' another controller; once the promise from Service is resolved, it then passes its own $scope on to the wrapped controller as well as the now-resolved data from Service.

Note that I've used $timeout to provide a 1000ms delay on the promise return, to try and make it a little more clear what's happening and when.

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;
  });

<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>

这篇关于Angularjs NG-控制器决心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆