2015-09-29 3 views
3

Я новичок в Angular и заявляет и обворачиваю голову вокруг ui-router. Я делаю это с jQuery слишком долго. В jQuery я могу загрузить что-то с помощью ajax, а затем на успех, возможно, запустить другую функцию. Как вы это делаете с помощью Angular?Ui-router загружает состояние, тогда как я могу запустить функцию?

Например, я следующий

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

ivApp.config(function($urlRouterProvider, $stateProvider){ 

    $urlRouterProvider.otherwise('/'); 

    $stateProvider 
    .state('home', { 
     url: '/', 
     templateUrl: 'partials/partial-home.html' 
    }) 

}); 

который просто загружает до partial-home.html в мою ui-view. Но как сказать, чтобы запустить функцию, когда это будет сделано? Например, у меня есть authenticate.js и функция authenticate(). Как запустить аутентификацию() после загрузки состояния «home»?

Кроме того, могу ли я указать угловые, чтобы загружать только authenticate.js для этого состояния? Или я должен был уже загрузить его в шаблон. Я знаю, что если я включу скрипт в partial-home.html (например, <script src="authenticate.js"></script>), хром выдаст мне ошибку, когда синхронный xmlhttprest устарел. Так что как-то в конфиге, могу ли я объявить authenticat.js как зависимость состояния или что-то в этом роде?

В настоящее время я работал, что я могу сделать что-то вроде:

ivApp.controller('authenticate', function($scope) { 

    // start authorisation 
    authenticate(); 

}); 

А затем определить подлинность контроллера в моем Ui-маршрутизатор состояний. Но так ли это? Он работает в основном. Моя функция аутентификации выполняет такие вещи, как изменение вещей в DOM, но я читаю, что контроллеры не должны использоваться для этого.

Спасибо за любые указатели

+0

Контроллер в порядке, но я думаю, что более рекомендуется использовать сервис для такого рода вещей. Если вам необходимо выполнить загрузку страницы при успешной аутентификации, используйте опцию 'resolve' в ui-router. –

+0

Хорошо, спасибо @SimonH. Я не уверен, как создать сервис и ввести с помощью ui-router, хотя – willdanceforfun

ответ

2

Перейдем к деталям.

Если вы хотите загрузить authenticate.js в этом качестве home, то используйте ocLazyLoad. Это один из лучших способов загрузки ресурса лениво. И это работает очень хорошо, если ui-router тоже!

$stateProvider.state('index', { 
     url: "/", // root route 
     views: { 
     "lazyLoadView": { 
      controller: 'AppCtrl', // This view will use AppCtrl loaded below in the resolve 
      templateUrl: 'partial-home.html' 
     } 
     }, 
     resolve: { // Any property in resolve should return a promise and is executed before the view is loaded 
     loadMyCtrl: ['$ocLazyLoad', function($ocLazyLoad) { 
      // you can lazy load files for an existing module 
       return $ocLazyLoad.load('js/authenticate.js'); 
     }] 
     } 
    }); 

Если вы хотите запустить authenticate() после загрузки состояния, есть довольно много способов сделать это. Один из способов, конечно, слушать событие $stateChangeSuccess, но я бы избегал использовать его, поскольку вы знаете, глобальные переменные и глобальные переменные являются плохими. Я не хочу загрязнять свой $rootScope только потому, что у меня есть действительно конкретный прецедент.

Вы также можете использовать resolve в ui-router. Resolve выполняется после загрузки состояния и перед созданием контроллера. Я бы рекомендовал использовать этот метод, поскольку вы можете связать свои обещания вместе с ocLazyLoad, если вы его используете (что вам нужно).

Манипулирование DOM после загрузки состояния? Конечно, вот что templateUrl для! Создайте свой шаблон таким образом, чтобы он соответствовал вашим функциям authenticate(). Если вы объедините его с resolve, на самом деле проблема не связана с проблемой, так как вы уже выполнили бы authenticate() перед загрузкой контроллера.

Edit: Добавление в Plnkr

Вы хотите первый лениво нагрузки authenticate.js, а затем использовать функцию внутриauthenticate.js сделать что-то. Поскольку resolve в ui.router выполняет параллельные цепочки обещаний, мы должны их связать, то есть сначала загрузите файлы jsfiles, а затем верните статус проверки подлинности.

Мы должны объявить отложенное обещание, используя услугу $q. Затем мы возвращаем это обещание в разрешении, чтобы вы контролировали одно обещание вместо двух. Вот так:

$stateProvider 
    .state('Home', { 
    templateUrl: 'home.html', 
    controller: 'homeCtrl', 
    resolve: { 
     //need to chain our promises since we neeed to first load the authenticate.js 
     //and second, execute authenticate() 
     loadJsAndAuth: ['$ocLazyLoad', '$q', '$injector', function($ocLazyLoad, $q, $injector) { 
     //declare a deferred promise 
     var deferred = $q.defer(); 

     //now load the authenticate.js 
     $ocLazyLoad.load('authenticate.js').then(
      //load successful! proceed to use our authenticate function! 
      function(success) { 
      //since we already have loaded authenticatejs, now we can inject the service and use it 
      var authSvc = $injector.get('authenticateSvc'); 

      //this is just a demo on how to authenticate. 
      //change this to banana to see the authenticate fail 
      var fruits = 'apple' 

      if (authSvc.authenticate(fruits)) { 
       //authenticate pass, resolve the promise! 
       deferred.resolve('authenticated!'); 
      } 
      //authenticate fail, reject the promise 
      deferred.reject('authenticate failed'); 

      }, 
      //load of jsfiles failed! reject the promise. 
      function(error) { 
      deferred.reject('Cannot load authenticate.js') 
      }) 

     return deferred.promise; 
     }] 
    } 
    }) 

И в вашем контроллере вы можете получить разрешенные обещания!

//you can get access to what is is being resolved by loadJsAndAuth 
.controller('homeCtrl', ['$scope', 'loadJsAndAuth', function($scope, loadJsAndAuth) { 

    $scope.status = loadJsAndAuth // this is resolved promises. 

}]); 
+0

Интересно. Так что это ленивая загрузка? Я постараюсь сделать то, что вы сказали, и заглянуть назад! Спасибо – willdanceforfun

+0

Отредактирован ответ, а также добавлен в plnkr, надеюсь, поможет вам в некотором роде ..: D – CozyAzure

+0

Это твердое. Спасибо чувак! – willdanceforfun

Смежные вопросы