Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度-@ViewChild来自我的模块_Javascript_Angular_Dom_Module_Viewchild - Fatal编程技术网

Javascript 角度-@ViewChild来自我的模块

Javascript 角度-@ViewChild来自我的模块,javascript,angular,dom,module,viewchild,Javascript,Angular,Dom,Module,Viewchild,我的问题是关于角度2/4/5模块 从模块中使用@ViewChild时无法使其工作,因为该子项未定义。在我把它作为一个简单的组件使用之前,它工作得很好。 *也尝试了@ViewChildren。。。同样的 代码示例- app.module.ts- import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { MyNewModule} from

我的问题是关于角度2/4/5模块

从模块中使用@ViewChild时无法使其工作,因为该子项未定义。在我把它作为一个简单的组件使用之前,它工作得很好。 *也尝试了@ViewChildren。。。同样的

代码示例-

app.module.ts-

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { MyNewModule} from './modules/MyNewModule/MyNewModule.module';

import { AppComponent } from './app.component';


@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    MyNewModule,
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule { }
app.component.ts-

import { Component, OnInit } from '@angular/core';
import { MyNewModule} from './modules/MyNewModule/MyNewModule.module';
@Component({
  selector: 'app-root',
  template: `<button (click)="Print()">Print child</button>
             <my-new-module></my-new-module>
            `,
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  constructor(private MyModule:MyNewModule){}

  ngOnInit(){}

  Print(){
   this.MyModule.Print();
  }

}
模块/MyNewModule/MyNewModule.ts-

import { Component, OnInit, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';

@Component({
  selector: 'my-new-module',
  template:`<ng-template #Container></ng-template>`
})
export class MyNewModule implements OnInit {

@ViewChild('Container', {read: ViewContainerRef}) private container: ViewContainerRef;

constructor(){}

ngOnInit(){}

Print(){
  console.log(this.container); => undefined
}



}
从'@angular/core'导入{Component,OnInit,ViewChild,ViewContainerRef,ComponentFactoryResolver};
@组成部分({
选择器:“我的新模块”,
模板:``
})
导出类MyNewModule实现OnInit{
@ViewChild('Container',{read:ViewContainerRef})私有容器:ViewContainerRef;
构造函数(){}
ngOnInit(){}
打印(){
console.log(this.container);=>未定义
}
}
在尝试在线搜索答案时,我发现唯一的解决方案是尝试@ViewChildren,或者它可能会发生,因为视图还没有初始化。所以我甚至试着在5秒钟的超时时间内完成。。。同样的结果。 再次使用相同的代码,但作为一个简单的应用程序,而不是模块,效果很好


谢谢阅读!:)

您需要一个ViewChild来引用模板的TemplateRef和ViewContainerRef。使用
ComponentResolverFactory
创建组件,然后使用组件视图参考创建嵌入式视图

@Component({
    selector: 'widget',
    template: '<ng-template #view></ng-template>'
})

export class WidgetComponent implements OnInit {
    @ViewChild('view', { read: ViewContainerRef }) view: ViewContainerRef;
    @ViewChild('view') template: TemplateRef<any>;

    constructor(private factory: ComponentResolverFactory, private viewRef: ViewContainerRef) { }

    ngOnInit() { 
         let component = ... some Type<any>...
         let componentFactory = this.factory.resolveComponentFactory(component);
         let ref:ComponentRef<any> = view.createComponent(componentFactory);
         this.factory.create(this.view, this.message.component);
         this.viewRef.createEmbeddedView(this.template);

    }
}
@组件({
选择器:“小部件”,
模板:“”
})
导出类WidgetComponent实现OnInit{
@ViewChild('view',{read:ViewContainerRef})view:ViewContainerRef;
@ViewChild(“视图”)模板:TemplateRef;
构造函数(私有工厂:ComponentResolverFactory,私有viewRef:ViewContainerRef){}
ngOnInit(){
让组件=…某个类型。。。
让componentFactory=this.factory.resolveComponentFactory(component);
let ref:ComponentRef=view.createComponent(componentFactory);
this.factory.create(this.view、this.message.component);
this.viewRef.createEmbeddedView(this.template);
}
}

正如我从评论中了解到的,您希望为组件创建功能模块,并在项目中重用它

我建议您看看这个组件库及其页面。它们具有设计良好的体系结构,即组件的功能模块

让我们从头开始,构建可重用组件

我用angular cli创建了一个新应用程序

ng新建我的项目

然后,我为稍后将要开发的组件创建了一个功能模块。我们称之为MyComponent

ng生成模块我的组件

然后创建了一个同名的组件

ng生成组件我的组件

然后我编辑MyComponent,如下所示

@NgModule({
    imports: [CommonModule],
    declarations: [MyComponentComponent],
    exports: [MyComponentComponent]
})
export class MyComponentModule { }
my-component.component.ts

@Component({
    selector: 'my-component',
    template: `
        <h1>My Component</h1>
        <div #container>
            <ng-content></ng-content>
        </div>
    `,
    styleUrls: ['./my-component.component.css']
})
export class MyComponentComponent implements OnInit, AfterContentInit {

    @ViewChild('container') container: ElementRef;

    constructor() { }

    ngOnInit() {
        console.log(this.container);
    }

    // this life cycle method is called after projected content is initialized.
    ngAfterContentInit() {
        console.log(this.container);
    }

    someMethod() {
    // do something ...
    }
}
@Component({
    selector: 'app-root',
    template: `
        <button (click)="onButtonClick()">Click me</button>
        <my-component>
            <div>This is from app component</div>
        </my-component>
    `,
})
export class AppComponent {

    @ViewChild(MyComponentComponent) myComponent: MyComponentComponent;

    onButtonClick() {
        this.myComponent.someMethod();
    }
}
然后,在我的
app.module.ts
中导入此模块,并在
app.component

此外,如果您想访问
app.component
中的
my component
,您可以使用
ViewChild

app.component.ts

@Component({
    selector: 'my-component',
    template: `
        <h1>My Component</h1>
        <div #container>
            <ng-content></ng-content>
        </div>
    `,
    styleUrls: ['./my-component.component.css']
})
export class MyComponentComponent implements OnInit, AfterContentInit {

    @ViewChild('container') container: ElementRef;

    constructor() { }

    ngOnInit() {
        console.log(this.container);
    }

    // this life cycle method is called after projected content is initialized.
    ngAfterContentInit() {
        console.log(this.container);
    }

    someMethod() {
    // do something ...
    }
}
@Component({
    selector: 'app-root',
    template: `
        <button (click)="onButtonClick()">Click me</button>
        <my-component>
            <div>This is from app component</div>
        </my-component>
    `,
})
export class AppComponent {

    @ViewChild(MyComponentComponent) myComponent: MyComponentComponent;

    onButtonClick() {
        this.myComponent.someMethod();
    }
}
要将其导入您的
应用程序组件

app.component.ts

@Component({
    selector: 'my-component',
    template: `
        <h1>My Component</h1>
        <div #container>
            <ng-content></ng-content>
        </div>
    `,
    styleUrls: ['./my-component.component.css']
})
export class MyComponentComponent implements OnInit, AfterContentInit {

    @ViewChild('container') container: ElementRef;

    constructor() { }

    ngOnInit() {
        console.log(this.container);
    }

    // this life cycle method is called after projected content is initialized.
    ngAfterContentInit() {
        console.log(this.container);
    }

    someMethod() {
    // do something ...
    }
}
@Component({
    selector: 'app-root',
    template: `
        <button (click)="onButtonClick()">Click me</button>
        <my-component>
            <div>This is from app component</div>
        </my-component>
    `,
})
export class AppComponent {

    @ViewChild(MyComponentComponent) myComponent: MyComponentComponent;

    onButtonClick() {
        this.myComponent.someMethod();
    }
}
从'your library/my component.module'导入{mycomponent}

您可以从同一位置导入模块

app.module.ts

export {MyComponentComponent} from './my-component.component.ts';

@NgModule({
    ...
})
export class MyComponentModule {}

从'your library/my component.module'导入{MyComponentModule}

在哪里调用
Print()
?为什么将组件命名为
MyNewModule
而不是
MyNewComponent
?我认为这给你带来了一些问题。此外,您不能将组件放入
提供程序
数组。@Und3rTow已修复,添加到app.component.ts模板:)@BunyaminCoskuner我不是,只是为了这个演示。将其从提供程序数组GG中移除会给我一个错误-staticInjectorError为什么要尝试将角度模块注入组件?为什么我需要一个ViewContainerRef来创建模板?为什么我需要为它生成一个组件?仅仅添加到app.component模板不是很好吗?太棒了,这正是我需要的!MyComponentComponent的@ViewChild是我所缺少的,现在我只需要构建模块并将其发布到npm。非常感谢您提供的信息answer@Ben我很高兴你喜欢我的回答。我更新了它并添加了一个链接。你可以使用ng packagr。如果你可以的话,我还有一个问题。。。显然,MyComponentComponent需要导入app.component.ts中才能使用。我不是要把它添加到模块导出数组中吗?如果不从其他位置单独导入它,我如何使用它?是的,您必须从“../my component/my component.component.ts
添加
import{MyComponentComponent},因为您在代码中使用它的类型。Typescript需要知道它来自哪里。但它不同于角度导入。这只是ES6模块导入。为了简单起见,我省略了
import
语句,但您需要它们。