Issues loading controller angular.js

时间:2015-07-31 19:40:14

标签: angularjs angular-ui-router

I'm trying to inject my controllers in AngularJS using the ui.router resolve, but i'm having issues where the template is loading first. My app.js is defined below:

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

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

    $urlRouterProvider.otherwise('/');

    $stateProvider
        .state('view1', {
            url: "/view1/",
            templateUrl: "view1/view1.html",
            resolve: {'': appendStaticFileToPage("view1/view1.js")}
        })

        .state('view2', {
            url: "/view2/",
            templateUrl: "view2/view2.html",
            resolve: {'': appendStaticFileToPage("view2/view2.js")}
        })

    ;

    function appendStaticFileToPage(file) {
        return function($q){
            var script = document.createElement('script');
            script.setAttribute('src', file);
            document.getElementsByTagName('head')[0].appendChild(script);
        };
    }

});

When the user clicks on a particular link for a state, I inject the js file for it into the browser. That part works fine. But the templateUrl defines the template to be used and that always loads first. Since it defines an ng-controller what happens is that the controller is being loaded, but since its not in the page yet, I get an error in the console that the controller couldn't be found. How can I achieve this?

I have created a simplified version of my code here:

http://plnkr.co/edit/X9uFOMIJq5tCn7VezSzT?p=preview

Is there a way to achieve what I am doing here?

EDIT

I previously had promises on my append code, which I'm showing below:

function appendStaticFileToPage(file) {
    return function($q){
        var deferred = $q.defer();

        var script = document.createElement('script');
        script.setAttribute('src', file);
        document.getElementsByTagName('head')[0].appendChild(script).ready(function(){
            deferred.resolve();
        });

        return deferred.promise;
    };
}

When I do this, nothing happens. It doesn't load the template. It also doesn't show the console.log statements I put in the controllers.

1 个答案:

答案 0 :(得分:1)

由于使用.controller注册它并不起作用,我可以确认脚本正在正确加载并执行,我尝试注入$controllerProvider服务并通过那里注册控制器,它工作正常

app.config(function($stateProvider, $urlRouterProvider, $controllerProvider) {

    $urlRouterProvider.otherwise('/');

    $stateProvider
        .state('view1', {
            url: "/view1/",
            templateUrl: "view1.html",
            resolve: {'': appendStaticFileToPage("view1.js", "MyViewOneController")}
        })

        .state('view2', {
            url: "/view2/",
            templateUrl: "view2.html",
            resolve: {'': appendStaticFileToPage("view2.js", "MyViewTwoController")}
        })

    ;

    function appendStaticFileToPage(file, controllerName) {
        return function($q){
            var deferred = $q.defer();

            var script = document.createElement('script');
            script.onload = function () {
                $controllerProvider.register(controllerName, window[controllerName])
                deferred.resolve();
            };
            script.onerror = function () {
                deferred.reject();
            };
            script.setAttribute('src', file);
            document.getElementsByTagName('head')[0].appendChild(script);

            return deferred.promise;
        };
    }

});

我还必须更新view1.js和view2.js,如下所示:

'use strict';
window.MyViewOneController = function($scope) {
  console.log("Got to view 1");
};