Angular (ionic) stateprovider templateUrl breaking

2019-09-05 20:54发布

问题:

This is a weird one and I'm just about giving up on it. I'm making an app in Ionic, and it allowed me to add states just fine, like this:

 $stateProvider
        .state('menu', {
            url: "/menu",
            templateUrl: "templates/menu.html",
            controller: "mainCtrl"
        })
        .state('products', {
            url: "/products",
            templateUrl: "templates/products.html",
            controller: "productsCtrl"
        })

etc. I have a few states there and it was all working fine a couple of days ago. I came back to the project today and added a new state - and it breaks. I added the new state the exact same way as the old ones - even copy-pasting when I saw it didn't work.
What happens is that the browser starts requesting the default over and over again (many times per second) and no template ever loads.

Now for the weird part. This is my new state:

.state('settings',{
            url: "/settings",
            templateUrl: "templates/settings.html",
            controller: "settingsCtrl"
        })

BUT when I change the templateUrl to template and insert directly the entire contents of the template file - it works perfectly.

That template file is located in the exact same location as the others which do work and don't break the app.

Update:It also works if I make templateUrl a function which returns the absolute path to the file (though not the relative one like the others have). maybe it's a caching issue somehow?

Maybe there's something else I need to do? I'm new to Ionic and to Angular.

UPDATE This is my entire app.js

angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])

.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins.Keyboard) {
  cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
  // org.apache.cordova.statusbar required
  StatusBar.styleDefault();
   }
});
})

.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
    $locationProvider.html5Mode({
        enabled: true,
        requireBase: false
    });

    $stateProvider
        .state('menu', {
            url: "/menu",
            templateUrl: "templates/menu.html",
            controller: "mainCtrl"
        })
        .state('products', {
            url: "/products",
            templateUrl: "templates/products.html",
            controller: "productsCtrl"
        })
        .state('settings',{
            url: "/settings",
            templateUrl: function (){return "myproject/www/templates/settings.html"},
            controller: "settingsCtrl"
        })
        .state('leads', {
            abstract: true,
            url: "/leads",
            template: '<ion-nav-view></ion-nav-view>'
        })
        .state('leads.index', {
            url : "",
            templateUrl: "templates/leads.html",
            controller: "leadsCtrl"
        })
        .state('leads.detail', {
            url: '/{lead_id}',
            templateUrl: "templates/lead.html",
            controller: "leadCtrl",
            resolve:
            {
                lead_id: function ($stateParams) {
                    return $stateParams.lead_id}
            }
        })
    $urlRouterProvider.otherwise('/menu');
});

回答1:

Add a listener for $stateChangeError, $stateChangeStart and $stateChangeSuccess and log to console - and you suddenly see exactly what happens in your app. Should be easy to fix afterwards.

See here for an example: angularjs routes, how to check if template file exists



回答2:

It is hard to say, where is your issue. So I created working plunker, with the settings shown below. Please, observe it and compare with your local version. It could help you to reveal the issue

$locationProvider.html5Mode({
    enabled: true,
    requireBase: false,
});

$stateProvider
    .state('menu', {
        url: "/menu",
        templateUrl: "templates/menu.html",
        controller: "mainCtrl",
    })
    .state('products', {
        url: "/products",
        views : {
          "products" : {
            templateUrl: "templates/products.html",
            controller: "productsCtrl"
          }
        }
    })
    .state('settings',{
        url: "/settings",
        //templateUrl: function (){return "myproject/www/templates/settings.html"},
        views : {
          "settings" : {
            templateUrl: "templates/settings.html", 
            controller: "settingsCtrl"
          }
        }
    })

And this is the index.html

<body ng-app="starter" animation="slide-left-right-ios7">    

    <ion-tabs class="tabs-icon-top">

      <ion-tab title="Menu" icon="icon ion-home" href="menu">
        <ion-nav-view name=""></ion-nav-view>
      </ion-tab>

      <ion-tab title="Products" icon="icon ion-person" href="/products">
        <ion-nav-view name="products"></ion-nav-view>
      </ion-tab>

      <ion-tab title="Settings" icon="icon ion-settings" href="/settings">
        <ion-nav-view name="settings"></ion-nav-view>
      </ion-tab>

    </ion-tabs>

</body> 

Check it in action here