简体   繁体   English

如何有条件地将资产包括在 <head> 与角

[英]How to conditionally include assets in the <head> with Angular

I am building a one-page Angular app. 我正在构建一页Angular应用程序。 One of the views has content which depends on an external javascript library. 其中一个视图的内容取决于外部javascript库。

I don't want to include this external JS resource on every view of the site, just the single view which depends on it. 我不想在网站的每个视图中都包含此外部JS资源,而仅依赖于该视图。

What is the best way to conditionally include blocks of code based on the current view? 基于当前视图有条件地包含代码块的最佳方法是什么?

If it's possible I'm hoping I can place in the something like this: 如果有可能,我希望可以放入以下内容:

<script ng-if="view == 'view1'" type='text/javascript' src='http://webplayer.unity3d.com/download_webplayer-3.x/3.0/uo/UnityObject2.js'></script>

So you should include the library script in page. 因此,您应该在页面中包含库脚本。

Then within directive bound to elements it needs to act on do the initialization. 然后在绑定到元素的指令中,需要对其进行初始化。

app.directive('unity', function () {
    return {
        link: function (scope, element, attrs) {
            // element is jQuery object when jQuery.js is included in page 
            // before angular - or it is a jQLite object similar to a jQuery object

            // config code

            u.initPlugin(element[0], "web_ovar_beta.unity3d");
        }
    }
});

Usage in view: 使用情况:

<div unity></div>

This can easily be expanded to pass in attributes to the directive from controller 这可以轻松扩展以将属性从控制器传递给指令

It is 它是

<script ng-if="view == 'view1'" type='text/javascript' ng-src='http://webplayer.unity3d.com/download_webplayer-3.x/3.0/uo/UnityObject2.js'></script>

And it is something that you don't want to do. 这是您不想做的事情。 It doesn't guarantee that the script won't be loaded twice. 它不能保证脚本不会被加载两次。 Since the script is being used for particular view, make it one-time resolving service 由于该脚本用于特定视图,因此使其成为一次性解决服务

app.factory('unityResolver', function ($document, $rootScope, $q, $timeout) {
  var deferred = $q.defer();
  var script = angular.element('<script>')[0]; 

  script.src = '...';
  script.async = true;
  script.onload = script.onreadystatechange = function () {
    if (['loaded', 'complete', undefined].indexOf(script.readyState) < 0)
      return;

    script.onload = script.onreadystatechange = null;

    deferred.resolve();
    $rootScope.$apply();
  }

  script.onerror = function onerror() {
    script.onerror = null;

    deferred.reject();
    $rootScope.$apply();
  };

  $timeout(onerror, 20000);
  $document.find('head').append(script);

  return deferred.promise;
});

and use it in view/route resolve . 并在view / route resolve使用它。

What your wanting to in turn is impossible. 您想要的又是不可能的。

You can get Javascript to include a javascript file if you want however if your using AJAX to load the content that is needed leave it in there it would be the same amount of time to load anyway. 如果需要,可以使Javascript包含一个javascript文件,但是,如果使用AJAX加载所需的内容,则将其保留在那里,无论如何都将花费相同的时间。 but once a file has been loaded into JavaScript it finished with you can remove the file from your HTML but the JavaScript engine still has the content of that file loaded in to it. 但是将文件加载到JavaScript后,您可以将其从HTML中删除,但是JavaScript引擎仍将文件的内容加载到其中。

Try it in your browsers(chrome or FF with Firebug) inspector now: open a new tab and go to about:blank then put the code below into the console 立即在您的浏览器(Chrome或FF中使用Firebug)检查器中尝试:打开一个新标签并转到about:blank然后将下面的代码放入控制台

var include = (function(){
   // the reference to the script
   var theScript;

   return function (filename, status){
     if(status == 'on'){
       // adding a script tag
       var head = document.getElementsByTagName('head')[0];

       theScript= document.createElement('script');
       theScript.src = filename;
       theScript.type = "text/javascript";

       head.appendChild( theScript )
     }else{
       // removing it again
       theScript.parentNode.removeChild( theScript );
     }
   }
})();

taken from Remove specific <script> tag in <head> tag by onclick event 取自onclick事件从<head>标记中删除特定的<script>标记

then in your inspector's console 然后在检查员的控制台中

include("https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js", 'on')

now check Elements and you will see jQuery loaded in the pages head tag. 现在检查Elements,您将看到jQuery加载在页面的head标记中。 and type jQuery into console and you will see function (a,b){return new n.fn.init(a,b)} 并在控制台中输入jQuery ,您将看到function (a,b){return new n.fn.init(a,b)}

And then use this into your console 然后在控制台中使用它

include("https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js", 'off')

and check your elements tab again the script tag will have gone. 并再次检查“元素”标签,脚本标记将消失。 however go back to console and type jQuery again and you will see function (a,b){return new n.fn.init(a,b)} as even though you have unloaded the file you can't remove the executed code from memory. 但是回到控制台并再次键入jQuery ,您将看到function (a,b){return new n.fn.init(a,b)} ,即使您已卸载文件,也无法从中删除执行的代码记忆。

You have 2 options another framework page gets loaded into an iFrame or if you want to use Anagular to load the View in then just include the file in your head there is no point not having and then removing it as once it is loaded it's loaded 您有2个选择,可以将另一个框架页面加载到iFrame中,或者如果您想使用Anagular加载View,则只需将文件包含在头部就可以了,然后在加载完成后将其删除

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM