Angular UI-Router Abstract父状态解析数据

时间:2015-11-28 20:08:56

标签: javascript angularjs templates angular-ui-router

我有以下ui-router州配置:

angular
.module('my_app', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider, $locationProvider){
    $urlRouterProvider.otherwise('/');
    $stateProvider
    .state('main', {
        abstract: true,
        views: {
            "header": {
                templateUrl: "app/views/shared/header.html",
                controller: "MainController",
                controllerAs: "main"
            },
            "content": {
                template: "<ui-view />"
            }
        },
        resolve: {
            mobile: mobileCheck
        }
    })
    .state('main.home', {
        url: '/',
        templateUrl: 'app/views/templates/home.html',
        controller: 'HomeController',
        controllerAs: 'home',
    })
    .state('main.earn', {
        url: '/earn',
        templateUrl: 'app/views/templates/earn.html',
        controller: "EarnController",
        controllerAs: 'earn',
    })
    .state('main.vision', {
        url: '/vision',
        templateUrl: 'app/views/templates/vision.html',
        controller: "VisionController",
        controllerAs: "vision"
    })
    .state('main.contact', {
        url: '/contact',
        templateUrl: 'app/views/templates/contact.html',
        controller: "ContactController",
        controllerAs: "contact"
    })
});

这里,我有一个抽象的父状态main,每个子状态(main.homemain.earn等)都是应用程序中的不同页面。 存在抽象状态以使用通用模板,标题,在所有页面模板之上:

views: {
    "header": {
        templateUrl: "app/views/shared/header.html",
        controller: "MainController",
            controllerAs: "main"
        },
        "content": {
            template: "<ui-view />"
        }
    }

相应的html如下所示:

<body ng-controller="MainController as main" ng-cloak>
    <div ui-view='header'></div>
    <div ui-view='content'></div>

    <script src="app/app.js"></script>

    <!-- AngularJS Controllers -->
    <script src="app/controllers/mainController.js"></script>
    <script src="app/controllers/homeController.js"></script>
    <script src="app/controllers/earnController.js"></script>
</body>

header命名视图是标头被注入的位置,content视图包含每个页面模板。

正如您所看到的,我已经在整个文档的主体上定义了主控制器,并为特定页面模板提供了控制器别名,因此我应该能够同时访问home和{{ 1}}在我能够确认的任何页面模板中都有效。

然而,在主控制器内访问我已解析的数据并不起作用。我可以访问每个页面模板,但不能访问主要的&#34; parent&#34;控制器。每个页面控制器都会传递main依赖关系,然后它可以附加到用于检测移动/桌面环境的mobile。我宁愿能够在this内收到mobile依赖关系,但每当我尝试MainController时,我都会得到关于错误依赖注入的标准角度错误。

这让我相信解析数据会被解析到子状态(和控制器),但不能解析为父控制器。我认为这是因为1)父抽象状态没有.controller('MainController', function(mobile)和2)因为该状态的控制器是在主体上命名的,而不是在状态本身上命名。

如何将已解析的数据作为依赖项解析到我的主控制器中?我已经尝试在状态配置中命名控制器但是没有效果。

2 个答案:

答案 0 :(得分:0)

我在发布问题后不久解决了我的问题,但我认为我应该发布我的发现/答案。

重温我的目标是:

  1. 合并已命名和未命名的ui-view标记
  2. 将数据解析为父控制器并进入所有子状态
  3. 访问子控制器的html模板中的父控制器和子控制器。
  4. 我将介绍我如何从1到3解决每个问题,所有这些问题都涉及如何将数据解析为抽象状态及其子女的更大问题。

    首先,看看我的身体标签:

    <body ng-controller="MainController as main" ng-cloak>
    

    在body标签上而不是在状态提供者内部定义父控制器意味着任何已解析的数据都没有传递给正在实体化的MainController实例,而是被传递到{ {1}}我的配置中指定的实例。无论哪种方式,由于依赖注入问题,正文控制器导致应用程序崩溃。

    所以我从body标签中删除了MainController。然后,为了获得命名视图和注入页面的常规ng-controller标记,您可以在<ui-view>文件中创建两个名为ui-view的文件:

    index.html

    并在状态config:

    <div ui-view='header'></div>
    <div ui-view='content'></div>
    

    共享视图将从指定的templateURL加载,并且页面会被注入到.state('main', { abstract: true, views: { "header": { templateUrl: "app/views/shared/header.html", controller: "MainController", controllerAs: "main" }, "content": { template: "<ui-view />" } }, resolve: { mobile: mobileCheck } }) 标记内的ui-view

    所以我们已经解决了1和2.我们有两个命名视图,同时能够注入页面,所有控制器实例都接收到已解析的依赖项。但是现在,即使标题可以访问主控制器,content标记内的任何页面都不会出现。 不幸的是,在以下状态命名控制器:

    content

    也不起作用。

    然后,简单的技巧是在所有子视图上定义主控制器:

    .state('main', {
        controller: "MainController",
        controllerAs: "main",
        views: { ... }
    

    现在,共享视图可以访问父控制器,子模板可以访问两个控制器。因此,您可以在父控制器上定义公共状态,例如,如果环境是移动的,而不是在每个子控制器上定义它。

    注:

    因为主控制器在两个地方定义,所以主控制器实例化两次。您可以通过制作某种服务或其他东西并为父控制器提供共享变量来解决这个问题

答案 1 :(得分:0)

也许您可以通过provider提供服务或mobileCheck,这样您根本无需为自己的州解决问题?考虑

.provider('mobileCheck', function mobileCheck() {
  this.$get = function() {
    return {
      isMobile: function() {
        return true;
      }
    };
  };
})

.controller('MainController', function(mobileCheck) {
  var main = this;
  main.isMobile = mobileCheck.isMobile();
})

.config(function($stateProvider) {
  $stateProvider
    .state('main', {
      abstract: true,
      views: { 
        'header': {
          template: '<div>abstract state : main (isMobile {{ main.isMobile  }})</div>',
          controller: 'MainController',
          controllerAs: 'main'
        },
        'content': {
          template: '<ui-view />'
        }
      }
    })
    .state('main.home', {
      url: '/',
      template: '<div>concrete state : home  (isMobile {{ main.isMobile  }})</div>',
      controller: angular.noop
    });
});

使用HTML模板

<body ng-controller="MainController as main" ng-cloak>
  <div ui-view="header"></div>
  <div ui-view="content"></div>
  <hr>
  <div>
    <a ui-sref="main.home">main.home</a>
  </div>
</body>

会给你类似的东西

img