깜박임을 방지하기 위해 모델이로드 될 때까지 AngularJS 경로 변경 지연


321

AngularJS가 각 모델과 해당 서비스를 사용하여 데이터를 가져 오기 전까지 새로운 경로 표시지연시킬 수 있는 방법이 있는지 궁금합니다 (Gmail과 유사) .

예를 들어, ProjectsController모든 프로젝트를 나열하고 project_index.html이러한 프로젝트를 표시 한 템플릿 인 파일 Project.query()이있는 경우 새 페이지를 표시하기 전에 완전히 가져옵니다.

그때까지 이전 페이지는 계속 표시됩니다 (예를 들어, 다른 페이지를 탐색하고이 프로젝트 색인을보기로 결정한 경우).

답변:


374

$ routeProvider resolve 속성은 데이터가로드 될 때까지 경로 변경 지연을 허용합니다.

먼저 resolve이와 같은 속성을 가진 경로를 정의 하십시오.

angular.module('phonecat', ['phonecatFilters', 'phonecatServices', 'phonecatDirectives']).
  config(['$routeProvider', function($routeProvider) {
    $routeProvider.
      when('/phones', {
        templateUrl: 'partials/phone-list.html', 
        controller: PhoneListCtrl, 
        resolve: PhoneListCtrl.resolve}).
      when('/phones/:phoneId', {
        templateUrl: 'partials/phone-detail.html', 
        controller: PhoneDetailCtrl, 
        resolve: PhoneDetailCtrl.resolve}).
      otherwise({redirectTo: '/phones'});
}]);

통지 resolve속성이 노선에 정의되어 있습니다.

function PhoneListCtrl($scope, phones) {
  $scope.phones = phones;
  $scope.orderProp = 'age';
}

PhoneListCtrl.resolve = {
  phones: function(Phone, $q) {
    // see: https://groups.google.com/forum/?fromgroups=#!topic/angular/DGf7yyD4Oc4
    var deferred = $q.defer();
    Phone.query(function(successData) {
            deferred.resolve(successData); 
    }, function(errorData) {
            deferred.reject(); // you could optionally pass error data here
    });
    return deferred.promise;
  },
  delay: function($q, $defer) {
    var delay = $q.defer();
    $defer(delay.resolve, 1000);
    return delay.promise;
  }
}

컨트롤러 정의에는 컨트롤러 생성자가 사용할 수있는 것을 선언하는 resolve 객체가 포함되어 있습니다. 여기서는 phones컨트롤러에 주입되며 resolve속성에 정의됩니다 .

resolve.phones기능은 약속을 반환합니다. 모든 약속이 수집되고 모든 약속이 해결 될 때까지 경로 변경이 지연됩니다.

실무 데모 : http://mhevery.github.com/angular-phonecat/app/#/phones 출처 : https://github.com/mhevery/angular-phonecat/commit/ba33d3ec2d01b70eb5d3d531619bf90153496831


10
@MiskoHevery-컨트롤러가 모듈 안에 있고 함수가 아닌 문자열로 정의 된 경우 어떻게해야합니까? 당신처럼 리졸 브 속성을 어떻게 설정할 수 있습니까?
aar0n

53
이것이 angular.controller()타입 컨트롤러 정의 에서 어떻게 사용 됩니까? 에서 $routeProvider물건, 난 당신이 컨트롤러의 문자열 이름을 사용했다 생각했다.
Ben Lesh

6
angular.controller ()를 사용하고 최신 버전의 AngularJS를 사용하는 예는 무엇입니까?
Laurent

22
@blesh,를 사용할 angular.controller()때이 함수의 결과를 변수 ( var MyCtrl = angular.controller(...))에 할당 한 다음 추가 작업 ( )을 수행 할 수 MyCtrl.loadData = function(){..}있습니다. egghead의 비디오를 확인하면 코드가 바로 표시됩니다 : egghead.io/video/0uvAseNXDr0
petrkotek

17
컨트롤러를 전역에 배치하지 않고도 좋은 방법을 원합니다. 전 세계의 사람들과 쓰레기를 나누고 싶지 않습니다. 상수로 할 수는 있지만 해결 기능을 다른 곳이 아닌 컨트롤러에 / 컨트롤러에 넣을 수 있으면 좋을 것입니다.
Erik Honn

51

다음은 Angular 1.0.2에서 작동하는 최소 작업 예입니다.

주형:

<script type="text/ng-template" id="/editor-tpl.html">
    Editor Template {{datasets}}
</script>

<div ng-view>

</div>

자바 스크립트 :

function MyCtrl($scope, datasets) {    
    $scope.datasets = datasets;
}

MyCtrl.resolve = {
    datasets : function($q, $http) {
        var deferred = $q.defer();

        $http({method: 'GET', url: '/someUrl'})
            .success(function(data) {
                deferred.resolve(data)
            })
            .error(function(data){
                //actually you'd want deffered.reject(data) here
                //but to show what would happen on success..
                deferred.resolve("error value");
            });

        return deferred.promise;
    }
};

var myApp = angular.module('myApp', [], function($routeProvider) {
    $routeProvider.when('/', {
        templateUrl: '/editor-tpl.html',
        controller: MyCtrl,
        resolve: MyCtrl.resolve
    });
});​

http://jsfiddle.net/dTJ9N/3/

간소화 된 버전 :

$ http ()는 이미 약속 (이미 연기 됨)을 반환하므로 실제로는 자체 약속을 만들 필요가 없습니다. 따라서 MyCtrl을 단순화 할 수 있습니다. 해결하다 :

MyCtrl.resolve = {
    datasets : function($http) {
        return $http({
            method: 'GET', 
            url: 'http://fiddle.jshell.net/'
        });
    }
};

$ http ()의 결과에는 data , status , headersconfig 객체가 포함되므로 MyCtrl 본문을 다음과 같이 변경해야합니다.

$scope.datasets = datasets.data;

http://jsfiddle.net/dTJ9N/5/


나는 이와 같은 일을하려고하지만 정의되지 않은 '데이터 세트'를 주입하는 데 문제가 있습니다. 이견있는 사람?
Rob Bygrave

: mb21 이봐, 난 당신이이 질문에 나를 도울 수있을 것 같아요 stackoverflow.com/questions/14271713/...을
winduptoy

누군가이 답변을 app.controller ( 'MyCtrl') 형식으로 변환하도록 도와 줄 수 있습니까? jsfiddle.net/5usya/1 이 작동하지 않았습니다.
user1071182

나는 오류가 발생합니다 :Unknown provider: datasetsProvider <- datasets
chovy

데이터 세트를 다음과 같이 바꾸면 답을 더 간단하게 만들 수 있습니다.function($http) { return $http({method: 'GET', url: '/someUrl'}) .then( function(data){ return data;}, function(reason){return 'error value';} ); }
Morteza Tourani

32

최소화하기 쉬운 의존성 주입과 함께 angular.controller 메서드를 사용 하여이 작업을 수행하는 방법을 묻는 사람들이 있습니다. 방금이 일을 마치고 돌아와서 도와 줘야한다고 느꼈습니다. 내 해결책은 다음과 같습니다 (원래 질문과 Misko의 대답에서 채택 됨).

angular.module('phonecat', ['phonecatFilters', 'phonecatServices', 'phonecatDirectives']).
  config(['$routeProvider', function($routeProvider) {
    $routeProvider.
      when('/phones', {
        templateUrl: 'partials/phone-list.html', 
        controller: PhoneListCtrl, 
        resolve: { 
            phones: ["Phone", "$q", function(Phone, $q) {
                var deferred = $q.defer();
                Phone.query(function(successData) {
                  deferred.resolve(successData); 
                }, function(errorData) {
                  deferred.reject(); // you could optionally pass error data here
                });
                return deferred.promise;
             ]
            },
            delay: ["$q","$defer", function($q, $defer) {
               var delay = $q.defer();
               $defer(delay.resolve, 1000);
               return delay.promise;
              }
            ]
        },

        }).
      when('/phones/:phoneId', {
        templateUrl: 'partials/phone-detail.html', 
        controller: PhoneDetailCtrl, 
        resolve: PhoneDetailCtrl.resolve}).
      otherwise({redirectTo: '/phones'});
}]);

angular.controller("PhoneListCtrl", [ "$scope", "phones", ($scope, phones) {
  $scope.phones = phones;
  $scope.orderProp = 'age';
}]);

이 코드는 질문 / 가장 인기있는 답변에서 파생되었으므로 테스트되지 않았지만 최소화하기 쉬운 각도 코드를 만드는 방법을 이미 이해했다면 올바른 방향으로 보내야합니다. 내 코드에 필요하지 않은 부분은 '전화'의 해결 기능에 "전화"를 주입하거나 '지연'객체를 전혀 사용하지 않았습니다.

또한이 유튜브 비디오 ( http://www.youtube.com/watch?v=P6KITGRQujQ&list=UUKW92i7iQFuNILqQOUOCrFw&index=4&feature=plcp)를 추천합니다 )를

관심이 있으시면 내 코드 (커피 스크립트로 작성)를 붙여서 어떻게 작동하는지 확인할 수 있습니다.

참고로, 미리 여러 ​​모델에서 CRUD를 수행하는 데 도움이되는 일반 컨트롤러를 사용합니다.

appModule.config ['$routeProvider', ($routeProvider) ->
  genericControllers = ["boards","teachers","classrooms","students"]
  for controllerName in genericControllers
    $routeProvider
      .when "/#{controllerName}/",
        action: 'confirmLogin'
        controller: 'GenericController'
        controllerName: controllerName
        templateUrl: "/static/templates/#{controllerName}.html"
        resolve:
          items : ["$q", "$route", "$http", ($q, $route, $http) ->
             deferred = $q.defer()
             controllerName = $route.current.controllerName
             $http(
               method: "GET"
               url: "/api/#{controllerName}/"
             )
             .success (response) ->
               deferred.resolve(response.payload)
             .error (response) ->
               deferred.reject(response.message)

             return deferred.promise
          ]

  $routeProvider
    .otherwise
      redirectTo: '/'
      action: 'checkStatus'
]

appModule.controller "GenericController", ["$scope", "$route", "$http", "$cookies", "items", ($scope, $route, $http, $cookies, items) ->

  $scope.items = items
      #etc ....
    ]

귀하의 예에서 올바르게 추론 resolve합니까? 최근 버전의 Angular에서는 컨트롤러에서 함수 를 참조하는 것이 불가능하다는 시도가 실패 합니까? 그래서 여기에있는 것처럼 설정에서 바로 선언해야합니까?
XML

@ XMLilley 나는 그것이 사실이라고 확신합니다. 이 예제는 내가 썼을 때 1.1.2에서 나온 것입니다. 컨트롤러 내부에 해결하기위한 문서를 보지 못했습니다
bitwit

2
감사합니다. SO에 대한 많은 예제가 있지만 (여기의 상위 2 개와 같음) 모두 2012 년과 2013 년 초에 있습니다. 이는 우아한 접근 방식이지만 더 이상 사용되지 않는 것으로 보입니다. 가장 깨끗한 대안은 이제 약속의 대상인 개별 서비스를 작성하는 것 같습니다.
XML

고마워 이것은 나를 위해 일했다. 정의되지 않은 $defer서비스 에 대한 오류가 발생하는 다른 사용자는 AngularJS 버전 1.5.7에서 $timeout대신 사용하려고합니다 .
racl101

18

버전 1.1.5 이상의 일부인 이 commit$promise객체를 노출합니다.$resource . 이 커밋을 포함한 ngResource 버전은 다음과 같은 리소스를 확인할 수 있습니다.

$ routeProvider

resolve: {
    data: function(Resource) {
        return Resource.get().$promise;
    }
}

제어 장치

app.controller('ResourceCtrl', ['$scope', 'data', function($scope, data) {

    $scope.data = data;

}]);

해당 커밋이 포함 된 버전은 무엇입니까?
XML

최신 불안정 버전 (1.1.5)에는이 커밋이 포함됩니다. ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js
Maximilian Hoffmann

나는 덜 덜 장황한 접근법을 좋아한다. 실제 데이터 객체에서 약속을 작성하고 직접 전달하는 것이 좋을 것입니다. 그러나 이것은 코드가 너무 작아서 잘 작동합니다.
Sam Barnum

1
자원이 $ routeParams에 어떻게 액세스합니까? 예를 들면 다음과 같습니다 GET '/api/1/apps/:appId'.->- App.get({id: $routeParams.appId}).$promise();나는 이것을 사용할 수 없습니다
zeronone

2
@zeronone 당신 $route은 당신의 결심과 사용에 주입 합니다 $route.current.params. 주의, $routeParams여전히 이전 경로를 가리키고 있습니다.
Brice Stacey

16

이 스 니펫은 의존성 주입 친화적이며 ( ngminuglify의 조합으로도 사용 가능 )보다 우아한 도메인 기반 솔루션입니다.

아래 예제는 Phone 자원상수 phoneRoutes를 등록합니다 . 여기에는 해당 (전화) 도메인에 대한 모든 라우팅 정보가 포함됩니다. 제공된 답변에서 마음에 들지 않는 부분은 리졸 브 로직 의 위치였습니다. 메인 모듈은 컨트롤러에 리소스 인수가 제공되는 방식에 대해 아무것도 알지 못하거나 방해 해서는 안됩니다 . 이런 식으로 논리는 동일한 도메인에 유지됩니다.

참고 : ngmin을 사용 하고 있고 사용 하지 않는 경우 DI 배열 규칙을 사용하여 resolve 함수 만 작성하면됩니다.

angular.module('myApp').factory('Phone',function ($resource) {
  return $resource('/api/phone/:id', {id: '@id'});
}).constant('phoneRoutes', {
    '/phone': {
      templateUrl: 'app/phone/index.tmpl.html',
      controller: 'PhoneIndexController'
    },
    '/phone/create': {
      templateUrl: 'app/phone/edit.tmpl.html',
      controller: 'PhoneEditController',
      resolve: {
        phone: ['$route', 'Phone', function ($route, Phone) {
          return new Phone();
        }]
      }
    },
    '/phone/edit/:id': {
      templateUrl: 'app/phone/edit.tmpl.html',
      controller: 'PhoneEditController',
      resolve: {
        form: ['$route', 'Phone', function ($route, Phone) {
          return Phone.get({ id: $route.current.params.id }).$promise;
        }]
      }
    }
  });

다음 부분은 모듈이 구성 상태에있을 때 라우팅 데이터를 주입하여 $ routeProvider에 적용하는 것 입니다.

angular.module('myApp').config(function ($routeProvider, 
                                         phoneRoutes, 
                                         /* ... otherRoutes ... */) {

  $routeProvider.when('/', { templateUrl: 'app/main/index.tmpl.html' });

  // Loop through all paths provided by the injected route data.

  angular.forEach(phoneRoutes, function(routeData, path) {
    $routeProvider.when(path, routeData);
  });

  $routeProvider.otherwise({ redirectTo: '/' });

});

이 설정으로 경로 구성을 테스트하는 것도 매우 쉽습니다.

describe('phoneRoutes', function() {

  it('should match route configuration', function() {

    module('myApp');

    // Mock the Phone resource
    function PhoneMock() {}
    PhoneMock.get = function() { return {}; };

    module(function($provide) {
      $provide.value('Phone', FormMock);
    });

    inject(function($route, $location, $rootScope, phoneRoutes) {
      angular.forEach(phoneRoutes, function (routeData, path) {

        $location.path(path);
        $rootScope.$digest();

        expect($route.current.templateUrl).toBe(routeData.templateUrl);
        expect($route.current.controller).toBe(routeData.controller);
      });
    });
  });
});

내 최신 (다가오는) 실험 에서 그것을 완전히 볼 수 있습니다 . 이 방법은 나를 위해 잘 작동하지만, 난 정말 $ 인젝터의 건설 지연되지 않는 이유 궁금 아무것도 가 주입 감지 할 때 어떤 A는 약속 개체; 그것은 soooOOOOOooOOOOOOO를 훨씬 쉽게 만들 것입니다.

편집 : 사용 Angular v1.2 (rc2)


2
이 탁월한 답변은 "Angular"철학 (캡슐화 등)에 훨씬 부합하는 것 같습니다. 우리는 kudzu와 같은 코드베이스에서 로직이 크립되는 것을 막기 위해 의식적인 노력을 기울여야합니다.
zakdances

I really wonder why the $injector isn't delaying construction of anything when it detects injection of anything that is a promise object앱의 응답성에 부정적인 영향을 미치는 디자인 패턴을 장려 할 수 있기 때문에이 기능을 생략 한 것 같습니다. 이상적인 앱은 진정으로 비동기식이므로 해결하는 것이 가장 중요합니다.
zakdances

11

경로 표시를 지연 시키면 비동기 엉킴이 발생할 수 있습니다. 주요 엔티티의로드 상태를 추적하고 뷰에서이를 사용하는 것이 어떻습니까? 예를 들어 컨트롤러에서 ngResource에 대한 성공 및 오류 콜백을 모두 사용할 수 있습니다.

$scope.httpStatus = 0; // in progress
$scope.projects = $resource.query('/projects', function() {
    $scope.httpStatus = 200;
  }, function(response) {
    $scope.httpStatus = response.status;
  });

그런 다음 관점에서 무엇이든 할 수 있습니다.

<div ng-show="httpStatus == 0">
    Loading
</div>
<div ng-show="httpStatus == 200">
    Real stuff
    <div ng-repeat="project in projects">
         ...
    </div>
</div>
<div ng-show="httpStatus >= 400">
    Error, not found, etc. Could distinguish 4xx not found from 
    5xx server error even.
</div>

6
아마도 CSS 클래스와 DOM 요소를 다루는 것 이상으로 HTTP 상태를 뷰에 노출시키는 것이 옳지 않을 수도 있습니다. 아마도 같은 아이디어를 사용하지만 isValid () 및 isLoaded ()에서 추상 상태를 사용합니다.
jpsimons

1
이것은 실제로 최상의 분리 문제가 아니며 특정 객체에 의존하는 중첩 컨트롤러가있는 경우 충돌이 발생합니다.
null

상태 코드를 뷰에 노출시킬 때 컨트롤러 내의 범위 속성에 http 로직을 붙여서 바인딩 할 수 있습니다. 또한 백그라운드에서 발생하는 여러 아약스 호출을하는 경우 어쨌든이 작업을 수행하려고합니다.
KingOfHypocrites

문제가 단순히보기를 지연시키는 문제라면 문제가되지 않습니다. 그러나 확인은 뷰뿐만 아니라 컨트롤러 의 인스턴스화 를 지연해야하는 경우에 사용하는 것이 가장 좋습니다 . (예 : 컨트롤러가 연결되기 전에 컨트롤러가 지시문에 전달되어 JSON이로드되었는지 확인해야하는 경우) 문서에서 : "라우터는 컨트롤러가 모두 제거 되기 전에 라우터가 모두 해결되기를 기다릴 것 입니다. 인스턴스화 된 ".
Dan

8

위의 Misko 코드에서 근무했으며 이것이 내가 한 일입니다. 이 (가) $defer로 변경된 이후의 최신 솔루션 $timeout입니다. $timeout그러나 대체 하면 시간 초과 기간 (Misko의 코드에서 1 초) 동안 기다린 다음 시간 내에 해결되기를 바라는 데이터를 반환합니다. 이런 식으로 최대한 빨리 반환됩니다.

function PhoneListCtrl($scope, phones) {
  $scope.phones = phones;
  $scope.orderProp = 'age';
}

PhoneListCtrl.resolve = {

  phones: function($q, Phone) {
    var deferred = $q.defer();

    Phone.query(function(phones) {
        deferred.resolve(phones);
    });

    return deferred.promise;
  }
}

7

AngularJS 1.1.5 사용

AngularJS 1.1.5 구문을 사용하여 Justen의 답변에서 '전화'기능 업데이트 .

기발한:

phones: function($q, Phone) {
    var deferred = $q.defer();

    Phone.query(function(phones) {
        deferred.resolve(phones);
    });

    return deferred.promise;
}

업데이트 :

phones: function(Phone) {
    return Phone.query().$promise;
}

Angular 팀과 기여자 덕분에 훨씬 짧습니다. :)

이것은 Maximilian Hoffmann의 답변이기도합니다. 분명히 그 커밋은 그것을 1.1.5로 만들었습니다.


1
docs$promise 에서 아무것도 찾을 수없는 것 같습니다 . v2.0 이상에서 제거되었을 수 있습니다.
zakdances

1.2에서만 사용할 수 있습니다
Thomas

5

$ routeProvider resolve 속성을 사용 하여 데이터가로드 될 때까지 경로 변경을 지연시킬 수 있습니다 .

angular.module('app', ['ngRoute']).
  config(['$routeProvider', function($routeProvider, EntitiesCtrlResolve, EntityCtrlResolve) {
    $routeProvider.
      when('/entities', {
        templateUrl: 'entities.html', 
        controller: 'EntitiesCtrl', 
        resolve: EntitiesCtrlResolve
      }).
      when('/entity/:entityId', {
        templateUrl: 'entity.html', 
        controller: 'EntityCtrl', 
        resolve: EntityCtrlResolve
      }).
      otherwise({redirectTo: '/entities'});
}]);

resolve속성은 경로에 정의되어 있습니다.

EntitiesCtrlResolve하고 EntityCtrlResolve있습니다 일정 과 동일한 파일에 정의 된 객체 EntitiesCtrlEntityCtrl컨트롤러.

// EntitiesCtrl.js

angular.module('app').constant('EntitiesCtrlResolve', {
  Entities: function(EntitiesService) {
    return EntitiesService.getAll();
  }
});

angular.module('app').controller('EntitiesCtrl', function(Entities) {
  $scope.entities = Entities;

  // some code..
});

// EntityCtrl.js

angular.module('app').constant('EntityCtrlResolve', {
  Entity: function($route, EntitiesService) {
    return EntitiesService.getById($route.current.params.projectId);
  }
});

angular.module('app').controller('EntityCtrl', function(Entity) {
  $scope.entity = Entity;

  // some code..
});

3

AngularJS를 처음 접하는 개발자 팀이 이해하고 바로 작업 할 수 있기 때문에 darkporter의 아이디어가 마음에 듭니다.

나는 2 개의 div를 사용하는이 적응을 만들었습니다. 하나는 로더 바 용이고 다른 하나는 데이터가로드 된 후 표시되는 실제 내용입니다. 다른 곳에서는 오류 처리가 수행됩니다.

$ scope에 'ready'플래그를 추가하십시오.

$http({method: 'GET', url: '...'}).
    success(function(data, status, headers, config) {
        $scope.dataForView = data;      
        $scope.ready = true;  // <-- set true after loaded
    })
});

HTML보기에서 :

<div ng-show="!ready">

    <!-- Show loading graphic, e.g. Twitter Boostrap progress bar -->
    <div class="progress progress-striped active">
        <div class="bar" style="width: 100%;"></div>
    </div>

</div>

<div ng-show="ready">

    <!-- Real content goes here and will appear after loading -->

</div>

다음도 참조 : Boostrap 진행률 표시 줄 문서


여러 조각의 데이터를로드하는 경우 약간 떨어집니다. 모든 것이로드되었는지 어떻게 알 수 있습니까?
toxaq

이 답변을 2 월에 추가 한 이후로이 페이지에 대한 더 많은 활동이 진행되었습니다. 여기에 제안 된 것보다 지금이 문제를 해결하기 위해 Angular에서 더 나은 지원이있는 것 같습니다. 건배,
reggoodwin

조금 늦게 도착했지만 여러 데이터를 처리하는 것은 큰 문제가되지 않습니다. 각 요청마다 별도의 변수 (부울 : isReadyData1, isReadyData2 등)를 사용하고 $ scope.ready = isReadyData1 && isReadyData2 ...; 나를 위해 잘 작동합니다.

1

위의 답변을 좋아하고 그로부터 많은 것을 배웠지 만 위의 답변 대부분에서 누락 된 것이 있습니다.

서버의 첫 번째 요청에서 가져온 일부 데이터로 URL을 해결하는 비슷한 시나리오에 갇혔습니다. 내가 직면 한 문제는 약속이 무엇인지에 관한 것이었다 rejected.

나는 반환하는 데 사용되는 사용자 지정 공급자 사용되었다 Promise에 의해 해결 된 resolve의를$routeProvider 설정 단계의 시간을.

여기서 강조하고 싶은 when것은 이와 같은 개념입니다 .

URL 표시 줄에 URL이 표시된 다음 when컨트롤러와 뷰의 각 블록이 지금까지 잘 참조됩니다.

구성 단계 코드를 따르고 있다고 가정 해 보겠습니다.

App.when('/', {
   templateUrl: '/assets/campaigns/index.html',
   controller: 'CampaignListCtr',
   resolve : {
      Auth : function(){
         return AuthServiceProvider.auth('campaign');
      }
   }
})
// Default route
.otherwise({
   redirectTo: '/segments'
});

브라우저의 루트 URL에서 첫 번째 실행 블록이 호출되고 그렇지 않으면 otherwise호출됩니다.

주소 표시 줄 AuthServicePrivider.auth()기능이 rootUrl에 도달 한 시나리오 가 호출 된다고 상상해보십시오 .

의 약속이 반환됩니다 말할 수 거부 상태 무엇을 다음 ???

아무것도 렌더링되지 않습니다.

Otherwise 구성 블록에 정의되어 있지 않고 angularJs 구성 단계에 알려지지 않은 URL에 대해 블록이 실행되지 않습니다.

이 약속이 해결되지 않으면 해고되는 사건을 처리해야합니다. 고장 $routeChangeErorr이 발생하면$rootScope 됩니다.

아래 코드와 같이 캡처 할 수 있습니다.

$rootScope.$on('$routeChangeError', function(event, current, previous, rejection){
    // Use params in redirection logic.
    // event is the routeChangeEvent
    // current is the current url
    // previous is the previous url
    $location.path($rootScope.rootPath);
});

IMO 일반적으로 응용 프로그램 실행 블록에 이벤트 추적 코드를 넣는 것이 좋습니다. 이 코드는 응용 프로그램의 구성 단계 직후에 실행됩니다.

App.run(['$routeParams', '$rootScope', '$location', function($routeParams, $rootScope, $location){
   $rootScope.rootPath = "my custom path";
   // Event to listen to all the routeChangeErrors raised
   // by the resolve in config part of application
   $rootScope.$on('$routeChangeError', function(event, current, previous, rejection){
       // I am redirecting to rootPath I have set above.
       $location.path($rootScope.rootPath);
   });
}]);

이렇게하면 구성 단계에서 약속 실패를 처리 할 수 ​​있습니다.


0

화면 계층이 비활성화 된 복잡한 다중 레벨 슬라이딩 패널 인터페이스가 있습니다. 클릭 이벤트를 생성하여 상태를 실행하는 비활성화 화면 레이어에 지시문 작성

$state.go('account.stream.social.view');

깜박임 효과를 내고있었습니다. history.back () 대신 정상적으로 작동했지만 필자의 경우 항상 역사상 다시는 아닙니다. 그래서 내가 알아 낸 것은 state.go 대신 비활성화 화면에서 단순히 href 속성을 만들면 매력처럼 작동한다는 것입니다.

<a class="disable-screen" back></a>

지시문 '뒤로'

app.directive('back', [ '$rootScope', function($rootScope) {

    return {
        restrict : 'A',
        link : function(scope, element, attrs) {
            element.attr('href', $rootScope.previousState.replace(/\./gi, '/'));
        }
    };

} ]);

app.js 방금 이전 상태를 저장합니다

app.run(function($rootScope, $state) {      

    $rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {         

        $rootScope.previousState = fromState.name;
        $rootScope.currentState = toState.name;


    });
});

-2

가능한 해결책 중 하나는 모델을 사용하는 요소와 함께 ng-cloak 지시문을 사용하는 것입니다.

<div ng-cloak="">
  Value in  myModel is: {{myModel}}
</div>

나는 이것이 최소한의 노력을 필요로한다고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.