programing

AngularJS - UI 라우터 - 동적 뷰 구성 방법

megabox 2023. 3. 5. 09:41
반응형

AngularJS - UI 라우터 - 동적 뷰 구성 방법

데이터베이스를 통해 동적으로 ui-router를 사용하는 방법에 대한 문서를 찾기가 어려웠습니다.코스의 경우, 모든 것이 하드코드로 되어 있습니다.

마이슨:

[
   {
       "name": "root",
       "url": "/",
       "parent": "",
       "abstract": true,
       "views": [
            {"name": "header", "templateUrl": "/app/views/header.html"},            
            {"name" :"footer", "templateUrl": "/app/views/footer.html" }
       ]
   },
    {
        "name": "home",
        "url": "",
        "abstract" : false,
        "parent": "root",
        "views": [
            {"name": "container@", "templateUrl": "/app/views/content1.html"},            
            {"name" :"left@", "templateUrl": "/app/views/left1.html" }
       ]
    },
    {
        "name": "about",
        "url": "/about",
        "abstract": false,
        "parent": "root",
        "views": [
             {"name": "container@", "templateUrl": "/app/views/content2.html"},            
             {"name" :"left@", "templateUrl": "/app/views/left2.html" }
            ]
    }
]

내 앱:

'use strict';

var $stateProviderRef = null;
var $urlRouterProviderRef = null;

var app = angular.module('app', ['ngRoute', 'ui.router']);


 app.factory('menuItems', function ($http) {
    return {
      all: function () {
        return $http({
            url: '/app/jsonData/efstates.js',
            method: 'GET'
        });
    }
  };
 });


  app.config(function ($locationProvider, $urlRouterProvider, $stateProvider) {
    $urlRouterProviderRef = $urlRouterProvider;
    $stateProviderRef = $stateProvider;
    $locationProvider.html5Mode(false);
    $urlRouterProviderRef.otherwise("/");
  });


  app.run(['$q', '$rootScope', '$state', 'menuItems',
  function ($q, $rootScope, $state, menuItems) {
      menuItems.all().success(function (data) {
          angular.forEach(data, function (value, key) {                
              $stateProviderRef.state(name = value.name, {
                  "url": value.url,
                  "parent" : value.parent,
                  "abstract": value.abstract,
                  "views": {
                     // do not want the below hard coded, I want to loop
                     // through the respective json array objects and populate state & views 
                     // I can do this with everything but views.

                     // first loop
                     'header': { 'templateUrl': '/app/views/header.html' },
                     'footer': { 'templateUrl': '/app/views/footer.html' },

                     // second loop
                     'left@':  { 'templateUrl': '/app/views/left1.html' },
                     'container@': { 'templateUrl': '/app/views/container1.html' },

                     // third loop
                     'left@':  { 'templateUrl': '/app/views/left2.html' },
                     'container@': { 'templateUrl': '/app/views/container2.html' },
                }
            });
        });
        $state.go("home");
    });
 }]);

뷰를 동적으로 구성하는 데 어려움을 겪고 있습니다.좋은 생각 있어요?


갱신:

관심 있는 사람을 위해 라딤 쾰러의 답변을 플런커로 작성했습니다.도와주셔서 감사합니다.

ui-router는 angular를 위한 defacto 라우터라고 생각합니다.다이나믹하게 함으로써 큰 앱을 관리하기 쉬워집니다.

뷰를 동적으로 설정하는 방법을 나타내는 플런커가 있습니다.의 업데이트 버전.run()다음과 같습니다.

app.run(['$q', '$rootScope', '$state', '$http',
  function ($q, $rootScope, $state, $http) 
  {
    $http.get("myJson.json")
    .success(function(data)
    {
      angular.forEach(data, function (value, key) 
      { 
          var state = {
            "url": value.url,
            "parent" : value.parent,
            "abstract": value.abstract,
            "views": {}
          };

          // here we configure the views
          angular.forEach(value.views, function (view) 
          {
            state.views[view.name] = {
              templateUrl : view.templateUrl,
            };
          });

          $stateProviderRef.state(value.name, state);
      });
      $state.go("home");    
    });
}]);

여기서 모든 기능을 확인하세요.

더 많은 작업을 수행할 수 있는 향상된 버전을 추가해야 합니다.

이제 상태를 동적으로 로드합니다.$http,json상태를 정의합니다..run()

그러나 이제 URL을 사용하여 임의의 동적 상태로 이동할 수 있습니다(주소 표시줄에 배치하기만 하면 됩니다.

마법은 UI-Router에 내장되어 있습니다.다음 문서를 참조하십시오.

$urlRouterProvider

deferIntercept(defer)

로케이션 변경 대행 수신의 지연을 디세블로 합니다(이네이블).

URL 의 동기 동작을 커스터마이즈 하는 경우(를 들면, 이행을 연기해 현재의 URL 유지하는 경우)에는, 설정시에 이 메서드를 호출합니다.그런 다음 실행 시 자체 $locationChangeSuccess 이벤트핸들러를 설정한 후 콜합니다.

인용된 단편:

var app = angular.module('app', ['ui.router.router']);

app.config(function($urlRouterProvider) {

  // Prevent $urlRouter from automatically intercepting URL changes;
  // this allows you to configure custom behavior in between
  // location changes and route synchronization:
  $urlRouterProvider.deferIntercept();

}).run(function($rootScope, $urlRouter, UserService) {

  $rootScope.$on('$locationChangeSuccess', function(e) {
    // UserService is an example service for managing user state
    if (UserService.isLoggedIn()) return;

    // Prevent $urlRouter's default handler from firing
    e.preventDefault();

    UserService.handleLogin().then(function() {
      // Once the user has logged in, sync the current URL
      // to the router:
      $urlRouter.sync();
    });
  });

  // Configures $urlRouter's listener *after* your custom listener
  $urlRouter.listen();
});

업데이트된 플런커는 여기에 있습니다.이 시점에서 이 기능을 사용할 수 있게 되었습니다..otherwise()최근 정의된 상태로 이동하거나 URL로 이동하려면 다음과 같이 하십시오.

국면

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

    // Prevent $urlRouter from automatically intercepting URL changes;
    // this allows you to configure custom behavior in between
    // location changes and route synchronization:
    $urlRouterProvider.deferIntercept();
    $urlRouterProvider.otherwise('/other');
    
    $locationProvider.html5Mode({enabled: false});
    $stateProviderRef = $stateProvider;
});

국면

app.run(['$q', '$rootScope','$http', '$urlRouter',
  function ($q, $rootScope, $http, $urlRouter) 
  {
    $http
      .get("myJson.json")
      .success(function(data)
      {
        angular.forEach(data, function (value, key) 
        { 
          var state = {
            "url": value.url,
            "parent" : value.parent,
            "abstract": value.abstract,
            "views": {}
          };
          
          angular.forEach(value.views, function (view) 
          {
            state.views[view.name] = {
              templateUrl : view.templateUrl,
            };
          });

          $stateProviderRef.state(value.name, state);
        });
        // Configures $urlRouter's listener *after* your custom listener            
        $urlRouter.sync();
        $urlRouter.listen();
      });
}]);

업데이트된 플런커를 확인하십시오.

루트를 동적으로 추가하기 위한 다양한 접근 방식을 조사했습니다.ui.router.

우선 ngRouteProvider를 사용하여 repositoryi를 찾았고, 그 주요 아이디어는$stateProvider그리고 그것을 에 폐쇄적으로 저장한다..config위상을 확인한 후 이 차이를 사용하여 새로운 루트를 즉시 추가합니다.그것은 좋은 생각이고 개선될지도 모른다.프로바이더의 레퍼런스를 보존해, 시간과 장소를 불문하고 조작하는 것이, 보다 좋은 해결책이라고 생각합니다.예를 들어refsProvider:

angular
    .module('app.common', [])
        .provider('refs', ReferencesProvider);

const refs = {};

function ReferencesProvider() {
    this.$get = function () {
        return {
            get: function (name) {
              return refs[name];
        }
    };
};

this.injectRef = function (name, ref) {
        refs[name] = ref;
    };
}

사용.refsProvider:

angular.module('app', [
    'ui.router',
    'app.common',
    'app.side-menu',
])
    .config(AppRouts)
    .run(AppRun);

AppRouts.$inject = ['$stateProvider', '$urlRouterProvider', 'refsProvider'];

function AppRouts($stateProvider, $urlRouterProvider, refsProvider) {
    $urlRouterProvider.otherwise('/sign-in');
    $stateProvider
        .state('login', {
            url: '/sign-in',
            templateUrl: 'tpl/auth/sign-in.html',
            controller: 'AuthCtrl as vm'
        })
        .state('register', {
            url: '/register',
            templateUrl: 'tpl/auth/register.html',
            controller: 'AuthCtrl as vm'
        });

    refsProvider.injectRef('$urlRouterProvider', $urlRouterProvider);
    refsProvider.injectRef('$stateProvider', $stateProvider);

}

AppRun.$inject = ['SectionsFactory', 'MenuFactory', 'refs'];

function AppRun(sectionsFactory, menuFactory, refs) {
    let $stateProvider = refs.get('$stateProvider');
    // adding new states from different places
    sectionsFactory.extendStates($stateProvider);
    menuFactory.extendStates($stateProvider);
}

SectionsFactory그리고.MenuFactory선언/모든 상태를 로드하는 일반적인 장소입니다.

또 다른 아이디어는 각진 앱 단계가 존재하며 다음과 같은 추가 공급자에 의해 앱 상태를 확장합니다.

angular.module('app.side-menu', []);
    .provider('SideMenu', SideMenuProvider);

let menuItems = [
    {
        label: 'Home',
        active: false,
        icon: 'svg-side-menu-home',
        url: '/app',
        state: 'app',
        templateUrl: 'tpl/home/dasboard.html',
        controller: 'HomeCtrl'
    }, {
        label: 'Charts',
        active: false,
        icon: 'svg-side-menu-chart-pie',
        url: '/charts',
        state: 'charts',
        templateUrl: 'tpl/charts/main-charts.html'
    }, {
        label: 'Settings',
        active: false,
        icon: 'svg-side-menu-settings',
        url: '/'
    }
];
const defaultExistState = menuItems[0].state;

function SideMenuProvider() {
    this.$get = function () {
        return {
            get items() {
                return menuItems;
            }
        };
    };
    this.extendStates = ExtendStates;
}

function ExtendStates($stateProvider) {
    menuItems.forEach(function (item) {
        if (item.state) {
            let stateObj = {
                url: item.url,
                templateUrl: item.templateUrl,
                controllerAs: 'vm'
            };
            if (item.controller) {
                stateObj.controller = `${item.controller} as vm`;
            }
            $stateProvider.state(item.state, stateObj);
        } else {
            item.state = defaultExistState;
        }
    });
}

는 굳이 in in in 、 음 、 음 、 음 、 음 、 in 、 in 、 in 、 in 、 in 、 in 、 in in in in in in in 。.run상태 및 핑거 상태 단계AppRouts위의 예에서 다음과 같이 변경됩니다.

AppRouts.$inject = ['$stateProvider', '$urlRouterProvider', 'SideMenuProvider'];

function AppRouts($stateProvider, $urlRouterProvider, SideMenuProvider) {
    $urlRouterProvider.otherwise('/sign-in');
    $stateProvider
        .state('login', {
            url: '/sign-in',
            templateUrl: 'tpl/auth/sign-in.html',
            controller: 'AuthCtrl as vm'
        })
        .state('register', {
            url: '/register',
            templateUrl: 'tpl/auth/register.html',
            controller: 'AuthCtrl as vm'
        })

    SideMenuProvider.extendStates($stateProvider);
}

모든 볼 수 : ,, 든, 든, 든, 든, 모, 모, also, also, also, also, also, also, also, also, also, also, also 등.SideMenu.items

언급URL : https://stackoverflow.com/questions/24727042/angularjs-ui-router-how-to-configure-dynamic-views

반응형