NgUpgrade:升级Angular1组件时无法使用templateUrl

Hou*_*oua 9 angularjs ng-upgrade angular

我想升级ng1组件以在ng2组件中使用.

如果我只使用模板字符串ng1组件,要升级,它的工作原理.但是,如果我切换到使用templateUrl,应用程序崩溃并给我这个错误:

angular.js:13920 Error: loading directive templates asynchronously is not supported
at RemoteUrlComponent.UpgradeComponent.compileTemplate (upgrade-static.umd.js:720)
at RemoteUrlComponent.UpgradeComponent (upgrade-static.umd.js:521)
at new RemoteUrlComponent (remote-url.component.ts:11)
at new Wrapper_RemoteUrlComponent (wrapper.ngfactory.js:7)
at View_AppComponent1.createInternal (component.ngfactory.js:73)
at View_AppComponent1.AppView.create (core.umd.js:12262)
at TemplateRef_.createEmbeddedView (core.umd.js:9320)
at ViewContainerRef_.createEmbeddedView (core.umd.js:9552)
at eval (common.umd.js:1670)
at DefaultIterableDiffer.forEachOperation (core.umd.js:4653)
Run Code Online (Sandbox Code Playgroud)

这是一个证明我的问题的插件:

https://plnkr.co/edit/2fXvfc?p=info

我遵循了Angular 1 - > 2升级指南,似乎这段代码应该可行.我不太确定为什么它不起作用.

小智 9

在尝试使用 requireJS 和对我不起作用的文本插件后,我设法使用“ng-include”使其工作,如下所示:

angular.module('appName').component('nameComponent', {
template: `<ng-include src="'path_to_file/file-name.html'"></ng-include>`,
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助!


小智 7

我找到了一个非常便宜的解决方案.

只是使用template: require('./remote-url.component.html')而不是templateUrl: './remote-url.component.html'它应该工作得很好!


小智 5

这确实令人沮丧,因为 Angular 升级文档明确表示可以使用 templateUrl。从来没有提到这个异步问题。我通过使用 $templateCache 找到了解决方法。我不想更改我的 Angular 1 指令,因为它用于我的 Angular 1 应用程序,并且也将由 Angular 4 应用程序使用。所以我必须找到一种即时修改它的方法。我使用了 $delegate、$provider 和 $templateCache。我的代码如下。我还使用它来删除替换属性,因为它已被弃用。

function upgradeDirective(moduleName, invokedName) {
    /** get the invoked directive */
    angular.module(moduleName).config(config);

    config.$inject = ['$provide'];
    decorator.$inject = ['$delegate', '$templateCache'];

    function config($provide) {
        $provide.decorator(invokedName + 'Directive', decorator);
    }

    function decorator($delegate, $templateCache) {
        /** get the directive reference */
        var directive = $delegate[0];

        /** remove deprecated attributes */
        if (directive.hasOwnProperty('replace')){
            delete directive.replace;
        }

        /** check for templateUrl and get template from cache */
        if (directive.hasOwnProperty('templateUrl')){
            /** get the template key */
            var key = directive.templateUrl.substring(directive.templateUrl.indexOf('app/'));

            /** remove templateUrl */
            delete directive.templateUrl;

            /** add template and get from cache */
            directive.template = $templateCache.get(key);
        }

        /** return the delegate */
        return $delegate;
    }
}

upgradeDirective('moduleName', 'moduleDirectiveName');
Run Code Online (Sandbox Code Playgroud)


Dan*_*ing 5

这里给出的大多数答案都涉及以某种方式预加载模板,以便使其与指令同步可用。

如果您想避免这样做 - 例如,如果您有一个包含许多模板的大型 AngularJS 应用程序,并且您不想预先下载所有模板 - 您可以简单地将指令包装在同步加载的版本中。

例如,如果您有一个名为 的指令myDirective,其中有一个异步加载的指令templateUrl,而您不想预先下载该指令,则可以这样做:

angular
  .module('my-module')
  .directive('myDirectiveWrapper', function() {
    return {
      restrict: 'E',
      template: "<my-directive></my-directive>",
    }
  });
Run Code Online (Sandbox Code Playgroud)

然后你的升级 Angular 指令只需要提供'myDirectiveWrapper'而不是'myDirective'在它的super()调用中扩展UpgradeComponent.