0

I am using gulp-angular-templatecache to convert all of my filename.view.html files into a templates.js file.

I'm then using $stateProvider to create my states and pull in the templates using $templateCache, with an abstract "root" state.

$stateProvider
    .state('app', {
        abstract: true,
        template: '<div ui-view></div>'
    })
    .state('app.login', {
        url: '/login',
        template: $templateCache.get('components/login/login.html'),
        controller: 'LoginController as login'
    });

Up to this point everything works fine. The templates load into my page just as they should, but no matter what I do I cannot get the controllers to work.

My modules and associated controllers are relatively simple:

(function () {

    'use strict';

    angular
        .module('login', [])
        .controller('LoginController', LoginController);

    function LoginController () {

        var vm = this;

        vm.loginID = 'test';
        vm.password = 'test';

        vm.doLoginRequest = function () {
            console.log('Performing login request...');
        }

    }

})();

I have tried a few different ways around this but none have appeared to work:

  • Moved template into the .run(...) section of the module and pushed it into $templateCache there instead
  • Different variations of template, templateUrl and templateProvider inside of the state config
  • Removing the controllerAs syntax from the state and using ng-controller instead
  • Using the old-style controller syntax (i.e. not controllerAs syntax)

Does anyone have any suggestions on how I may resolve this issue? I've been tearing my hair our for hours!

Manno
  • 399
  • 1
  • 3
  • 12
  • How are you including your controller's `login` module. Also you don't need to call `$templateCache.get()`. You can just do `templateUrl: 'components/login/login.html'`. – rob Jun 08 '16 at 00:03
  • Is your routes defined as config under the login module? Which module are your routes defined? – Ajai Jun 08 '16 at 00:03
  • The `login` module is just included as a dependency of my main application module. All of my routes are defined together in a `.config(...)` block as part of the main application module e.g. `angular.module('app', ['login']).config(function ($stateProvider) { .... });` – Manno Jun 08 '16 at 00:06
  • I'm not showing dependency injection here for sake of space, but I assure you I am using dependency injection correctly too :) – Manno Jun 08 '16 at 00:07
  • @rob thanks for confirming I can just use templateUrl. I've updated those now but my issue remains :( – Manno Jun 08 '16 at 00:09
  • @Pot-Nut You have defined your routes under your app module but you have defined your controller under login module. This could cause problems as angular will not be able to see LogincController from app module since its not defined in it. Not sure if that is the exact problem but you could try changing the routes to individual modules or moving the controller to your app module. – Ajai Jun 08 '16 at 00:13
  • @Ajai I have tried setting up the routes under their appropriate modules but for some reason UI Router didn't like this approach. I'll try doing this again and come back to you. That being said, I have used a similar setup to my current setup in two other Angular projects and both work fine! Strange... – Manno Jun 08 '16 at 00:17
  • @Ajai Unfortunately my routes no longer load at all if I move them into their appropriate modules :( – Manno Jun 08 '16 at 00:26
  • @Pot-Nut The ui-router docs suggest having a url for the abstract state (https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views#abstract-state-usage-examples). Could you try it with a url? Something like `url: '/'` or `url: ''` – Ajai Jun 08 '16 at 00:36
  • @Ajai I have just tried this. Using `url: '/'` just gave me URLs like www.app.local//login and did not fix the controllers. Using `url: ''` worked better for the URLs but did not fix the controllers either. I have uploaded a copy of the application to my website and edited my question to provide the link if that helps you narrow down the issue :) – Manno Jun 08 '16 at 00:40
  • @Pot-Nut In your routes, can you try this ```{ state: 'r6stats.login', config: { url : '/login', views: { '': { controller: 'LoginController as login', templateUrl: 'components/login/login.html' } } } }``` instead of the `@` – Ajai Jun 08 '16 at 00:45
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/114077/discussion-between-pot-nut-and-ajai). – Manno Jun 08 '16 at 00:47

2 Answers2

0

How to preload templates:

1) Run your task, to generate template.js view

2) In your index file, pre-load all templates

  <script src="build/templates.js"></script>

3) Include your module as dependency (auto tasks usually create a separate module, make sure you check, what's the name of the module)

angular.module('app', ['templates'])

4) In app.config section just reference the views as if you were loading them without cache

 .state('home', {
        url: '/home',
        views: {
            "@": {
                controller: 'homeController',
                templateUrl: 'app/views/home.html'

            },
        }

    })
JanisP
  • 1,233
  • 15
  • 16
  • I am already doing steps 1-3 and the templates are showing fine in my application. It's only the controllers that do not work. I have tried using your `.state` setup as detailed in step 4 but my route then no longer shows at all (and does not throw any errors in my console). – Manno Jun 08 '16 at 00:25
  • I recall seeing `@` used on its own instead of `content@` at some point when I was searching for solutions to my problem. I have tried this and the route then shows again but the controller still does not work. – Manno Jun 08 '16 at 00:29
  • @Pot-Nut content@ - that comes from your view markup. More documentation here: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views#view-names---relative-vs-absolute-names And I removed 'content' from the view, because that really can be misleading. In other words, it was looking for view, that is called 'content' and good that you found an issue – JanisP Jun 08 '16 at 01:40
0

It turns out that I was using a <form> element on my login template which for some reason Angular does like. I'm guessing I have implemented the <form> incorrectly in order for it to work with Angular.

Removing the <form> element resolves the issue.

Manno
  • 399
  • 1
  • 3
  • 12