如何让AngularJs UI-Router加载AngularJs 1.6.1应用程序的组件

时间:2017-01-14 00:50:46

标签: angularjs angular-ui-router

我已经按照UI-Router站点上的文档来说明我的配置$ StateProvider的代码实际上是相同的,但我无法加载我的组件。我能够看到我的templateUrl中引用的html页面,但是没有访问控制器。此外,当我在状态路由中提供Controller引用时,错误表明控制器未注册

索引页面上的第一个组件:

<supply-chain-admin ng-cloak></supply-chain-admin>

(function () {
"use strict"

var module = angular.module("SCAdmin");

function AppController($timeout) {

    var vm = this; // vm = ViewModel
    vm.isNewBlankLoad = false;
    vm.selectedMenuItem;
    vm.changeMenu = true;

    vm.$onInit = function () {
        vm.changeMenu = true;
    }

    vm.collapseMainMenu = function (isCollapsed) {
        vm.changeMenu = isCollapsed;
        $timeout(function () { equalheight('.menuListItem'); }, 10);
    };
}

module.component("supplyChainAdmin", {
    templateUrl: "/Scripts/SupplyChainAdmin/SCAdminApp/SupplyChainAdmin.html",
    bindings: {
    },
    controllerAs: "vm",
    controller: ['$timeout', AppController]
});

})();

这个组件里面的html文件:

<main-menu show-menu="vm.changeMenu"></main-menu>
<main-content show-menu="vm.changeMenu"></main-content>

在主菜单组件中:

<div id="menuleft" ng-class="{hideMenu:!vm.showMenu,slide:vm.showMenu}">
<div id="mainMenuHeader">
    <a class="pull-right" id="mainMenuToggleLink" ng-click="vm.toggleMenu()">
        <img src="/Content/images/menu.png" />
    </a>
</div>
<div id="mainMenu">
    <ul class="menuList" ng-class="{hideMenu:vm.showMenu,slide:!vm.showMenu}"><!-- the :: symbol represents one time binding -->
        <li title="{{ ::menuItem.ToolTip }}" class="menuListItem" ng-repeat="menuItem in vm.menuItems" ng-class="{ active: menuItem.Link == vm.selectedMenuItem }" resize-normal>
            <button class="menuNotifications pull-right" ng-show="menuItem.Notification.length" popover="{{ ::menuItem.NotificationMessage }}" popover-trigger="focus" popover-placement="right" popover-append-to-body="true">{{ ::menuItem.Notification }}</button>
            <a ng-click="vm.menuItemChanged(menuItem.Link)" ui-sref="{{ ::menuItem.Link }}">
                <h1 ng-show="vm.showMenu"><span class="{{ ::menuItem.MenuIconClass }}"></span> {{ ::menuItem.Title }} <i class="line"></i></h1>
                <p ng-hide="vm.showMenu"><span class="{{ ::menuItem.MenuIconClass }}"></span> <i class="line"></i></p>

                <div class="menuItemContent" ng-class="{hide:!vm.showMenu}">
                    <ul class="list-unstyled list-inline">
                        <li ng-repeat="pointItem in menuItem.MenuItemPoints">
                            <div class="fa large-glyphicon {{ ::pointItem.IconClass }}" aria-hidden="true"></div>
                            <div class="menuSubItemText">&nbsp;{{ ::pointItem.DisplayText }}&nbsp;</div>
                            <div class="menuSubItemValue">&nbsp;{{ ::pointItem.DisplayValue }}&nbsp;</div>
                        </li>
                    </ul>
                </div>
            </a>
        </li>
    </ul>
</div>

(function () {
"use strict"

var module = angular.module("SCAdmin");

module.component("mainMenu", {
    templateUrl: "/Scripts/SupplyChainAdmin/MainMenu/MainMenu.html",
    bindings: {
        showMenu: "="
    },
    controllerAs: "vm",
    controller: ["$http", '$timeout', '$state', mainMenuController]
});

function mainMenuController($http, $timeout, $state) {

    var vm = this; // vm = ViewModel

    vm.isNewBlankLoad = false;
    vm.menuItems = [];

    vm.selectedMenuItem;

    vm.$onInit = function () {
        fetchMenuItems($http, $state).then(function (data) {
            if (data.length) {

                for (var i = 0, l = data.length; i < l; i++) {
                    if (data[i].MenuItemType === 1) {

                        vm.menuItems.push({ Link: 'Items', ToolTip: 'Items', Title: 'My Items', MenuItemType: 1, Notification: data[i].Notification, NotificationMessage: data[i].NotificationMessage, MenuItemPoints: data[i].MenuItemPoints, MenuIconClass: 'fa fa-tags' });
                    }
                    if (data[i].MenuItemType === 2) {
                        vm.menuItems.push({ Link: 'Vendors', ToolTip: 'Vendor', Title: 'My Vendors', MenuItemType: 2, Notification: data[i].Notification, NotificationMessage: data[i].NotificationMessage, MenuItemPoints: data[i].MenuItemPoints, MenuIconClass: 'fa fa-id-card' });
                    }
                    if (data[i].MenuItemType === 3) {
                        vm.menuItems.push({ Link: 'Facilities', ToolTip: 'Facilities', Title: 'My Facilities', MenuItemType: 2, Notification: data[i].Notification, NotificationMessage: data[i].NotificationMessage, MenuItemPoints: data[i].MenuItemPoints, MenuIconClass: 'fa fa-university' });
                    }
                    if (data[i].MenuItemType === 4) {
                        vm.menuItems.push({ Link: 'Departments', ToolTip: 'Departments', Title: 'My Departments', MenuItemType: 2, Notification: data[i].Notification, NotificationMessage: data[i].NotificationMessage, MenuItemPoints: data[i].MenuItemPoints, MenuIconClass: 'fa fa-bed' });
                    }
                    if (data[i].MenuItemType === 5) {
                        vm.menuItems.push({ Link: 'Pars', ToolTip: 'Pars', Title: 'My PARs', MenuItemType: 2, Notification: data[i].Notification, NotificationMessage: data[i].NotificationMessage, MenuItemPoints: data[i].MenuItemPoints, MenuIconClass: 'fa fa-stethoscope' });
                    }
                    if (data[i].MenuItemType === 6) {
                        vm.menuItems.push({ Link: 'Maintenance', ToolTip: 'Maintenance', Title: 'Maintenance', MenuItemType: 2, Notification: data[i].Notification, NotificationMessage: data[i].NotificationMessage, MenuItemPoints: data[i].MenuItemPoints, MenuIconClass: 'fa fa-wrench' });
                    }
                }

                vm.selectedMenuItem = $state.current.name != null ? $state.current.name : vm.menuItems[0].ToolTip;
            }
        });
    };

    vm.menuItemChanged = function (selectMenuItem) {
        vm.selectedMenuItem = selectMenuItem;
    }

    vm.menuItems = vm.menuItems;

    vm.toggleMenu = function () {
        vm.showMenu = (vm.showMenu) ? false : true;
        $timeout(function () { equalheight('.menuListItem'); }, 10);
    }
}

function fetchMenuItems($http) {
    return $http.get(SupplyChainAdminUrl + 'Menu/GetMenuItems/', { params: { domain: CurrentUserDomain, userName: CurrentUserUserName } }).then(function (response) {
        return response.data;
    });
}

})();

在主要内容组件中:

<div id="contentFromMenu" ng-class="{hideMenu:vm.showMenu,slide:!vm.showMenu}">
<div class="overlay" ng-class="{show:vm.showMenu}" ng-click="vm.collapseMenu()"></div>
<div id="menuContentContainer">
    <ui-view></ui-view>
</div>

(function () {

"use strict"

var module = angular.module("SCAdmin");

module.component("mainContent", {
    templateUrl: "/Scripts/SupplyChainAdmin/MainContent/MainContent.html",
    require: {
        'parent': '^supplyChainAdmin'
    },
    bindings: {
        showMenu: "<"
    },
    controllerAs: "vm",
    controller: ["$http", '$timeout', mainContentController]

});

function mainContentController($timeout) {

    var vm = this; // vm = Viewvm

    vm.$onInit = function () {

    }

    vm.collapseMenu = function () {
        //the parameter sets the show menu property to false;
        vm.parent.collapseMainMenu(false);
    };
};

})();

app.js模块文件中的路由器:

(function () {
"use strict";

var app = angular.module("SCAdmin", ['ui.router', 'ui.bootstrap', 'jQueryScrollbar', 'ngSanitize', 'angular.vertilize']);

app.config(function ($stateProvider, $urlMatcherFactoryProvider, $urlRouterProvider, $locationProvider) {

    $urlRouterProvider.otherwise('/Items');
    $urlMatcherFactoryProvider.caseInsensitive(true);
    $locationProvider.html5Mode(true);

    $urlRouterProvider.rule(function ($injector, $location, $window, $timeout) {

        //We can write authorization / part access checks here.

        //what this function returns will be set as the $location.url
        var path = $location.path(), normalized = path.toLowerCase();

        if (path != normalized) {

            //alert(path);

            //instead of returning a new url string, I'll just change the $location.path directly so I don't have to worry about constructing a new url string and so a new state change is not triggered
            //$location.replace().path(normalized);
        }

        // because we've returned nothing, no state change occurs
    });

    $stateProvider
        .state('Items', {
            url: '/Items',
            component: 'items',
            templateUrl: '/Scripts/SupplyChainAdmin/Items/Items.html',
            //onEnter: function(){
            //    alert('entering the Items state');
            //}
        })
        .state('Vendors', {
            url: '/Vendors',
            component: 'Vendors',
            templateUrl: '/Scripts/SupplyChainAdmin/Vendors/Vendors.html',
        })
        .state('Vendors.VendorList', {
            url: '/List',
            templateUrl: '/Scripts/SupplyChainAdmin/Vendors/List/VendorList.html'
        })
        .state('Facilities', {
            url: '/Facilities',
            component: 'facilities',
            templateUrl: '/Scripts/SupplyChainAdmin/Facilities/Facilities.html',
        })
        .state('Departments', {
            url: '/Departments',
            component: 'departments',
            templateUrl: '/Scripts/SupplyChainAdmin/Departments/Departments.html',
        })
        .state('Pars', {
            url: '/Pars',
            component: 'pars',
            templateUrl: '/Scripts/SupplyChainAdmin/Pars/Pars.html',
        })
        .state('Maintenance', {
            url: '/Maintenance',
            component: 'maintenance',
            templateUrl: '/Scripts/SupplyChainAdmin/Maintenance/Maintenance.html',
        });
})

app.run(function ($rootScope, $timeout) {
    $rootScope.$on('$stateNotFound', function (event, unfoundState, fromState, fromParams) {
        event.preventDefault();
    });
    $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams, options) {
        $rootScope.stateIsLoading = true;
    });
    $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams, options) {
        $timeout(function () { $rootScope.stateIsLoading = false; }, 300);
    });
    $rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
        event.preventDefault();
        $timeout(function () { $rootScope.stateIsLoading = false; }, 300);
    });
    $rootScope.$on('$viewContentLoading', function (event, viewConfig) {
        //$rootScope.stateIsLoading = true;
    });
    $rootScope.$on('$viewContentLoaded', function (event, viewConfig) {
        //$rootScope.stateIsLoading = false;
    });
})

}());

我知道嵌套路由未正确配置。我的重点是&#34;项目&#34;这篇文章的状态。 html加载,但组件没有。

1 个答案:

答案 0 :(得分:-1)

似乎问题在于您的组件状态定义,例如:

.state('Vendors', {
        url: '/Vendors',
        component: 'Vendors',
        templateUrl: '/Scripts/SupplyChainAdmin/Vendors/Vendors.html',
    })

从最新的ui-router开始,您需要指定包含提供路由名称,网址,组件和解析程序的组件的路由(可选)

$stateProvider.state({
  name: 'Vendors',
  url: '/Vendors',
  component: 'Vendors'
});

您不需要在状态定义中提供templateUrl,因为您已经在组件的定义中设置了它。 此外,如果您更改网址但又不想重新加载网页,则可以提供其他状态定义参数reloadOnSearch : false 像:

$stateProvider.state({
  name: 'Vendors',
  url: '/Vendors',
  component: 'Vendors',
  reloadOnSearch : false
});

希望这有帮助。