简体   繁体   English

使用downgradeComponent时,无法加载Bootstrapped Angular 2 + Angular 1 Hybrid App

[英]Bootstrapped Angular 2 + Angular 1 Hybrid App not loading when using downgradeComponent

I have an Angular 1 app that I've followed the instructions from the official Angular tutorial ( https://angular.io/docs/ts/latest/guide/upgrade.html ) for Bootstrapping a hybrid 1+2 app. 我有一个Angular 1应用程序,我遵循官方Angular教程( https://angular.io/docs/ts/latest/guide/upgrade.html )的说明,用于Bootstrapping混合1 + 2应用程序。 I have all the code in place and run the app and absolutely nothing happens. 我有所有代码并运行应用程序,绝对没有任何反应。 It just goes to the root URL and I only get the styling and view of whatever is in index.html . 它只是转到根URL,我只获得index.html中任何内容的样式和视图。 However the main <div ng-view> never gets updated via $routeProvider and app.ts . 但是主<div ng-view>永远不会通过$routeProviderapp.ts更新。 At least that appears to be what's happening. 至少看起来是正在发生的事情。 There are zero errors. 零次失误。 Here is what I have so far: 这是我到目前为止:

main.ts (loaded via SystemJS) main.ts (通过SystemJS加载)

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { UpgradeModule } from '@angular/upgrade/static';
import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
    const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
    upgrade.bootstrap(document.body, ['MyA1App']);
});

One note for the above hybrid bootstrap code - it is working as far as I can tell. 上面的混合引导代码的一个注意事项 - 据我所知,它正在工作。 If I change the Angular1 app name to blahblah , I get a whole bunch of errors in the browser. 如果我将Angular1应用程序名称更改为blahblah ,我会在浏览器中收到大量错误。 This code can find the MyA1App Angular1 module defined in app.ts and is able to bootstrap it. 此代码可以找到MyA1App定义Angular1模块app.ts并能够引导它。

index.html : index.html

<div class="main-content" ng-view=""></div>

<!-- Configure SystemJS (bootstrap Angular 2 app) -->
<script src="systemjs.config.js"></script>
<script>
    System.import('app').catch(function(err){ console.error(err); });
</script>

<!-- Old Angular 1 bootstrap method -->
<!--<script>
    angular.bootstrap(document.body, ['MyA1App']);
</script>-->   

app.module.ts app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { UpgradeModule } from '@angular/upgrade/static'; //To bootstrap a hybrid application, we  need to import UpgradeModule in our AppModule, and override it's bootstrap method:

@NgModule({
    imports: [BrowserModule, UpgradeModule ],
})

export class AppModule {
    ngDoBootstrap() {}
}

import { downgradeComponent } from '@angular/upgrade/static';
angular.module('MyA1App', [])
    .directive(
    'contactList',
    downgradeComponent({ component: ContactListComponent }) as angular.IDirectiveFactory
    );

app.ts (from Angular 1, which defines the module and routing - this should still be in play and used) app.ts (来自Angular 1,它定义了模块和路由 - 这应该仍在使用中)

module MyApp {
    'use strict';

export var App: ng.IModule = angular.module('MyA1App', ['ngRoute', 'ngResource', 'highcharts-ng', 'ui.bootstrap']);

    //  register work which needs to be performed on module loading
    App.config([
        '$routeProvider', '$httpProvider',
        ($routeProvider: ng.route.IRouteProvider, $httpProvider: ng.IHttpProvider) => {

            $routeProvider
                .when('/landing',
                {
                    controller: MyApp.Controllers.LandingCtrl,
                    templateUrl: '/app/angular1x/partials/landing.html'
                })
                .when('/registration',
                {
                    controller: MyApp.Controllers.RegistrationCtrl,
                    controllerAs: 'vm',
                    templateUrl: '/app/angular1x/partials/registration.html'
                })               
                .otherwise({
                    redirectTo: '/landing'
                });
        }
    ]);   
}

So here's the overview of the issue: 所以这里是问题的概述:

  • Bootstraping to Angular2 main.ts via systemjs called in index.html (appears successful - no errors) 的Bootstrap到Angular2 main.ts通过systemjs称为index.html (似乎成功-没有错误)
  • I can place breakpoints in Angular1 controllers, Landing, etc. and see the controllers being defined and loaded being hit. 我可以在Angular1控制器,Landing等中放置断点,并查看正在定义和加载的控制器。 But nothing else happens! 但没有其他事情发生! No errors or anything. 没有错误或任何东西。
  • The ng-view directive is never updated via routing. ng-view指令永远不会通过路由更新。 Upon inspecting on the main page it just looks like: <div class="main-content" ng-view=""></div> 在主页上检查时,它看起来像: <div class="main-content" ng-view=""></div>
  • No JS errors anywhere 任何地方都没有JS错误
  • If I go back and use the original A1 bootstrap in index.html it works as opposed to using systemjs to load A2 and bootstrap A1 as a hybrid. 如果我返回并使用index.html的原始A1引导程序,则与使用systemjs加载A2和引导A1作为混合使用systemjs

What am I doing incorrectly here so that the original Angular1 app appears to load and bootstrap just fine, but isn't actually doing anything? 我在这里做错了什么,以便原来的Angular1应用程序看起来加载和引导很好,但实际上并没有做任何事情?


UPDATE: 更新:

I have tracked down the offending code to be the following in app.module.ts : 我在app.module.ts跟踪了违规代码:

import { downgradeComponent } from '@angular/upgrade/static';
angular.module('MyA1App', [])
    .directive(
    'contactList',
    downgradeComponent({ component: ContactListComponent }) as angular.IDirectiveFactory
    );

It was not the routing (that was a red herring). 这不是路由(那是一个红鲱鱼)。 The entire Angular1 app will bootstrap and load if I remove the code above. 如果我删除上面的代码,整个Angular1应用程序将自举并加载。 What am I doing in the code above that could cause everything to halt loading, yet not create any JavaScript errors? 我在上面的代码中做了什么,可能会导致一切停止加载,但不会创建任何JavaScript错误?

Well I got to the bottom of this issue and it's disappointing the length of time I waisted because of following the UPGRADING FROM 1.X tutorial. 好吧,我已经到了这个问题的最底层,因为我遵循了升级的1.X教程,所以我的时间长度令人失望。 In the tutorial, it shows this exact sample code to downgrade an Angular 2 component by registering it as a directive via the Angular 1 module: 在本教程中,它显示了通过Angular 1模块将Angular 2组件注册为directive来降级Angular 2组件的精确示例代码:

angular.module('heroApp', [])
  .directive(
    'heroDetail',
    downgradeComponent({component: HeroDetailComponent}) as angular.IDirectiveFactory
  );

Notice the empty brackets after the module name [] ? 注意模块名称[]后面的空括号? That was the issue. 就是问题所在。 It sent me on a wild goose chase because when I had that in which was directly from the tutorial, I started getting errors about my controllers in Angular1 not being defined. 它让我进行了一次疯狂的追逐,因为当我直接从教程中获得它时,我开始收到关于Angular1控制器没有被定义的错误。 Since a lot of this is still fresh, I went on a wild goose chase stripping parts of my A1 app trying to get things to work thinking they weren't compatible with A2 . 由于很多这个仍然是新鲜的,我继续疯狂追逐剥离我的A1应用程序的部分试图让事情发挥作用,认为他们与A2不兼容。 It wasn't until I read in that same tutorial that, "The existing Angular 1 code works as before and you're ready to run Angular 2 code" This led me to process of elimination that something in the A2 bootstrap code was wrong and ultimately the brackets caused nothing to load. 直到我在同一个教程中读到, “现有的Angular 1代码和以前一样工作,你已经准备好运行Angular 2代码了”这导致我消除了A2引导代码中的某些东西是错误的并且最终括号无法加载。

My OP noted I wasn't receiving any errors. 我的OP指出我没有收到任何错误。 This was because I had stripped a lot of A1 code trying to make things work and got to a point where the app loaded but nothing was displayed and thought it was a routing issue. 这是因为我已经剥离了大量的A1代码,试图让工作变得有效,并且达到应用程序加载的程度,但没有显示任何内容,并认为这是一个路由问题。

The working code for me is as follows: 我的工作代码如下:

angular.module('MyA1App')
    .directive('contactList', downgradeComponent({ component: ContactListComponent }) as angular.IDirectiveFactory);

I have two suggestions: 我有两个建议:

  1. In your index.html, change <div class="main-content" ng-view=""></div> into <div class="main-content" ui-view></div> . 在index.html中,将<div class="main-content" ng-view=""></div>更改为<div class="main-content" ui-view></div>

  2. remove <div class="main-content" ng-view=""></div> from index and add <root-cmp></root-cmp> 从index中删除<div class="main-content" ng-view=""></div>并添加<root-cmp></root-cmp>

Update your app.module.ts like this: 像这样更新你的app.module.ts:

@Component({  
  selector: 'root-cmp',  
  template: '<div class="main-content" ui-view></div>'  
})  
export class RootCmp {
}

@NgModule({  
  imports: [  
    BrowserModule,  
    UpgradeModule  
  ],  
  bootstrap: [RootCmp],  
  declarations: [
    RootCmp
  ],  
  providers: [],  
  entryComponents: [
    RootCmp
  ]  
})  
export class Ng2Module {
  ngDoBootstrap() {
  }
}  

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

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