簡體   English   中英

Ui-router加載狀態,那么我該如何運行一個函數呢?

[英]Ui-router loads state, then how can I run a function?

我是Angular的新手,並指出我的頭圍繞着ui-router。 我用jQuery做了太久了。 在jQuery中,我可以用ajax加載一些東西,然后在成功時加載,也許運行另一個函數。 你是怎么用Angular做的?

例如,我有以下內容

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()?

另外,我可以告訴angular只為這個狀態加載authenticate.js嗎? 或者我應該已經將其加載到模板中。 我知道如果我將該腳本包含在partial-home.html中(例如<script src="authenticate.js"></script> ),chrome會拋出一個關於同步xmlhttprest被棄用的錯誤。 所以somhow在配置中,我可以聲明authenticat.js作為狀態的依賴或類似的東西嗎?

在我鍛煉的那一刻,我可以做類似的事情:

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

  // start authorisation
  authenticate();

});

然后定義控制器在我的ui-router狀態中進行身份驗證。 但它是如何完成的? 它基本上有效。 我的身份驗證功能正在做更改DOM中的事情,但我不應該使用控制器。

謝謝你的任何指示

讓我們分解成幾部分。

如果您只想在此特定的home狀態下加載authenticate.js ,請使用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

您也可以在ui-router中使用resolve 在加載狀態之后實例化控制器之前執行Resolve 我建議使用這種方法,因為你可以將你的承諾與ocLazyLoad一起ocLazyLoad ,如果你正在使用它(你應該)。

在加載狀態后操縱DOM? 當然,這就是templateUrl用途! 設計您的模板,使其符合您的authenticate()函數。 如果將它與resolve結合使用,那么分離關注點並沒有太多問題,因為在加載控制器之前已經執行了authenticate()

編輯:在Plnkr中添加

你想先懶洋洋地加載authenticate.js ,然后用函數內部 authenticate.js做一些事情。 既然resolveui.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.

}]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM