加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angularjs-angular-ui-router与requirejs,延迟加载控制器

发布时间:2020-12-17 07:37:13 所属栏目:安全 来源:网络整理
导读:你可以帮助我了解如何在视图之前的下面的示例中加载控制器?看起来像在控制器尚未加载时立即加载视图. //app.js$stateProvider.state('index',{ url: "/",views: { "topMenu": { templateUrl: "/Home/TopMenu",controller: function($scope,$injector) { req
你可以帮助我了解如何在视图之前的下面的示例中加载控制器?看起来像在控制器尚未加载时立即加载视图.
//app.js
$stateProvider.state('index',{
    url: "/",views: {
        "topMenu": {
            templateUrl: "/Home/TopMenu",controller: function($scope,$injector) {
                require(['controllers/top-menu-controller'],function(module) {
                    $injector.invoke(module,this,{ '$scope': $scope });
                });
            }
        }
    }
});

//top-menu-controller.js
define(['app'],function (app) {
    app.controller('TopMenuCtrl',['$scope',function ($scope) {
        $scope.message = "It works";
    }]);
});

//Home/TopMenu
<h3>TopMenu</h3>
<div ng-controller="TopMenuCtrl">
    {{message}}
</div>
我 created working plunker这里.

我们有这个index.html:

<!DOCTYPE html>
<html>
  <head>
    <title>my lazy</title>    
  </head>

  <body ng-app="app">

      <a href="#/home">#/home</a>     // we have three states - 'home' is NOT lazy
      <a href="#/">#/</a>  - index    // 'index' is lazy,with two views
      <a href="#/other">#/other</a>   // 'other' is lazy with unnamed view

    <div data-ui-view="topMenu"></div>        
    <div data-ui-view=""></div>

    <script src="angular.js"></script>           // standard angular
    <script src="angular-ui-router.js"></script> // and ui-router scritps

    <script src="script.js"></script>            // our application

    <script data-main="main.js"                  // lazy dependencies
        src="require.js"></script>

  </body>    
</html>

让我们观察main.js – RequireJS配置:

require.config({

    //baseUrl: "js/scripts",baseUrl: "",// alias libraries paths
    paths: { 

        // here we define path to NAMES
        // to make controllers and their lazy-file-names independent

        "TopMenuCtrl": "Controller_TopMenu","ContentCtrl": "Controller_Content","OtherCtrl"  : "Controller_Other",},deps: ['app']
});

实际上,我们只为ControllerNames创建别名(路径)及其Controller_Scripts.js文件.而已.此外,我们返回要求应用程序,但是我们将在以后使用不同的功能 – 注册延迟加载的控制器.

deps:[‘app’]是什么意思?首先,我们需要提供文件app.js(‘app’表示find app.js):

define([],function() {

  var app = angular.module('app');
  return app; 
})

这个返回的值是我们可以在每个异步加载的文件中要求的值

define(['app'],function (app) {
    // here we would have access to the module("app")
});

我们如何懒惰地加载控制器?这在ngRoute已经被证明了

angularAMD v0.2.1

angularAMD is an utility that facilitates the use of RequireJS in AngularJS applications supporting on-demand loading of 3rd party modules such as angular-ui.

我们将要求角度参考$controllerProvider – 稍后再使用它来注册控制器.

这是我们的script.js的第一部分:

// I. the application
var app = angular.module('app',[
  "ui.router"
]);


// II. cached $controllerProvider
var app_cached_providers = {};

app.config(['$controllerProvider',function(controllerProvider) {
    app_cached_providers.$controllerProvider = controllerProvider;
  }
]);

我们可以看到,我们刚刚创建了应用程序“app”,并创建了持有人app_cached_providers(遵循angularAMD样式).在配置阶段,我们要求角度为$controllerProvider,并保留参考.

现在我们继续在script.js中:

// III. inline dependency expression
app.config(['$stateProvider','$urlRouterProvider',function($stateProvider,$urlRouterProvider) {

    $urlRouterProvider
      .otherwise("/home");

    $stateProvider
      .state("home",{
        url: "/home",template: "<div>this is home - not lazily loaded</div>"
      });

    $stateProvider
      .state("other",{
        url: "/other",template: "<div>The message from ctrl: {{message}}</div>",controller: "OtherCtrl",resolve: {
          loadOtherCtrl: ["$q",function($q) { 
            var deferred = $q.defer();
            require(["OtherCtrl"],function() { deferred.resolve(); });
            return deferred.promise;
          }],});

  }
]);

以上部分显示了两个州的声明.其中一个 – “家”是标准的没有懒惰的.它的控制器是隐含的,但可以使用标准.

第二个是状态命名为“other”,其目标是未命名的视图ui-view =“”.在这里我们可以先看看,懒惰的负载.里面的决心(见:)

Resolve

You can use resolve to provide your controller with content or data that is custom to the state. resolve is an optional map of dependencies which should be injected into the controller.

If any of these dependencies are promises,they will be resolved and converted to a value before the controller is instantiated and the $stateChangeSuccess event is fired.

在我们的套件中,我们知道,一旦解决完成,控制器(以其名称)将在角度存储库中进行搜索:

// this controller name will be searched - only once the resolve is finished
controller: "OtherCtrl",// let's ask RequireJS
resolve: {
  loadOtherCtrl: ["$q",function($q) { 
    // wee need $q to wait
    var deferred = $q.defer();
    // and make it resolved once require will load the file
    require(["OtherCtrl"],function() { deferred.resolve(); });
    return deferred.promise;
  }],

好的,现在,如上所述,主要包含这个别名def

// alias libraries paths
paths: {       
    ...
    "OtherCtrl"  : "Controller_Other",

这意味着文件“Controller_Other.js”将被搜索和加载.这是它的魔法的内容.这里最重要的是使用以前缓存的引用$controllerProvider

// content of the "Controller_Other.js"

define(['app'],function (app) {
    // the Default Controller
    // is added into the 'app' module
    // lazily,and only once
    app_cached_providers
      .$controllerProvider
      .register('OtherCtrl',function ($scope) {
        $scope.message = "OtherCtrl";
    });        
});

诀窍不是使用app.controller()但是

$controllerProvider.Register

The $controller service is used by Angular to create new controllers. This provider allows controller registration via the register() method.

最后还有另一种状态定义,更多的缩小了解决…试图使它更易读:

// IV ... build the object with helper functions
//        then assign to state provider    
var loadController = function(controllerName) {
  return ["$q",function($q) {
      var deferred = $q.defer();
      require([controllerName],function() {deferred.resolve(); });
      return deferred.promise;
  }];
}    

app.config(['$stateProvider',$urlRouterProvider) {

    var index = {
        url: "/",views: {
          "topMenu": {
            template: "<div>The message from ctrl: {{message}}</div>",controller: "TopMenuCtrl","": {
            template: "<div>The message from ctrl: {{message}}</div>",controller: "ContentCtrl",resolve : { },};        
    index.resolve.loadTopMenuCtrl = loadController("TopMenuCtrl");
    index.resolve.loadContentCtrl = loadController("ContentCtrl");

    $stateProvider
      .state("index",index);          
}]);

以上我们可以看到,我们为这个状态的/所有命名视图解析了两个控制器

而已.每个控制器在这里定义

paths: { 
    "TopMenuCtrl": "Controller_TopMenu",...
},

将通过resolve和$controllerProvider加载 – 通过RequireJS – 懒惰.检查所有here

类似问答答:AngularAMD + ui-router + dynamic controller name?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读