当指令的ng-switch-when被触发时,通过$ timeout加载外部脚本

时间:2014-11-20 19:43:09

标签: angularjs requirejs

我的指令创建如下:

elements.directive('myApp', function(){
return {
    restrict: 'E',
    templateUrl: "/path/to/myapp.html",
    controller: function($scope, $timeout) {
            // loads the script when the dom has finished rendering
        var loadScript = function() {
            var script = document.getElementById('myappjs');
            if(script){
                /*
                 * the script is already appended but needs to be re-executed
                 * - remove and re-append the script element?
                 * - $route.reload() in order to refresh the page?
                 * - other solutions
                */
            } else {
                // the script has never been loaded before and the script element is created from scratch
                var s = document.createElement('script');
                s.id = "myappjs";
                s.src = '/path/to/require.js';
                s.setAttribute('data-main', '/path/to/script');  //.js needs to be omitted

                document.body.appendChild(s);
            }
        };
        // when the DOM has finished rendering, loadScript is executed:
        $timeout(loadScript, 0);
    }
};
});

' my-app'元素放在ng-switch容器中。基本上它加载一个svg和脚本来执行它。 问题是该脚本仅在ng-switch第一次与“我的应用程序”匹配时执行。 element:如果我切换到' my-app'从另一个指令(总是在ng-switch容器内)它起作用。 但是,如果我再次转向另一个指令,然后再转到“我的应用程序”,那么该脚本就不再适用了。

当我发现之前已经附加了脚本时,我尝试使用$ route.reload(),但它会导致无限循环。 然后我尝试从DOM中删除脚本元素并重新附加它,但脚本无论如何都没有加载。

因此仅在我第一次访问页面时才加载svg的内容。 有没有人有任何建议?

1 个答案:

答案 0 :(得分:0)

我通过在run函数中包装外部JS的所有代码来解决:

/* app.js file */

var myAppRun = function() {
    /* the code of my app  */
}
myAppRun();

HTML开关:

<!-- select-page-template.html file -->
<div ng-switch on="selectedPage">
    <my-app ng-switch-default></my-app>     
    <another-directive ng-switch-when="another_directive"></another-directive>
</div>

和指令定义:

/* directives.js file*/
elements.directive('myApp', function(){
    return {
        restrict: 'E',
        templateUrl: "/path/to/myapp.html",
        controller: function($scope, $timeout) {
            var loadScript = function() {
                if(typeof myAppRun === "function"){
                myAppRun();
                return;
            }

                var s = document.createElement('script');
                    s.src = '/path/to/myapp.js';
                document.body.appendChild(s);
            };

                $timeout(loadScript, 0);
        }
    };
});

如果尚未定义myAppRun函数,则将创建脚本并将其附加到HTML正文。 myAppRun()将在myapp.js文件中自动执行。 否则每次ng-switch匹配默认条件时,都会在指令控制器中调用myAppRun()。

'loadScript'仅在使用$ timeout渲染DOM后执行。通过这种方式,myapp.js可以找到需要操作而不会抛出“未找到元素”错误的所有元素(例如myapp模板中的SVG元素)。