简体   繁体   English

父对象不可见Angular2新对象字段?

[英]Angular2 new Object fields not visible to parent?

So I have the following dumbed-down version of something I'm working on: 因此,我正在研究以下内容的简化版本:

tab.ts 标签

import {Component, OnInit} from "@angular/core";
@Component({
  selector: 'tab',
  template: `
<h1>{{title}} / {{deletable}}</h1>
`,
})
export class Tab implements OnInit{

  title: string;
  deletable: boolean;

  ngOnInit(): void {
    this.deletable=true;
    console.log("TITLE: "+this.title);
  }

}

app.ts 应用程序

import {Component, AfterViewInit} from '@angular/core';
import {Tab} from "./tab";

@Component({
  selector: 'my-app',
  template: `
<div *ngFor="let tab of tabs let i=index">
<tab></tab>
<button (click)="removeTab(i)">REMOVE</button>
</div>
<button (click)="addTab()">Add new tab</button>

`,
})
export class App implements AfterViewInit {

  tabs: Tab[] = [];

  ngAfterViewInit(): void {
    this.addTab();
  }

  addTab() {
    var tab = new Tab();
    tab.title = "List " + (this.tabs.length + 1);
    this.tabs.push(tab);
  }

  removeTab(index: number) {
    var tab = this.tabs[index];
    console.log("TITLE: "+tab.title);
    console.log("DELETABLE: "+tab.deletable);
    this.tabs.splice(index, 1);
  }

}

So, long story short, in this situation from the app component the console will log the correct title, while deletable will print undefined. 因此,长话短说,在这种情况下,控制台会从应用程序组件记录正确的标题,而可删除的内容将打印未定义。 Why is this? 为什么是这样? The other way around goes for the Tab component. 另一种方法是使用Tab组件。 Title will be undefined, but deletable won't be undefined, it will be true. 标题将是未定义的,但可删除的将不会是未定义的,它将是真实的。

Obviously, in my app the use case is different, I get some variables from a sub component of Tab based on some forms that are also created dynamically. 显然,在我的应用中,用例是不同的,我基于一些也可以动态创建的表单从Tab的子组件中获取了一些变量。 The problem is that if I try to access them from the parent app component they will be undefined as well, while they won't be undefined in the Tab component. 问题是,如果我尝试从父app组件访问它们,它们也将是未定义的,而在Tab组件中将不会是未定义的。

What pattern is used to work around this issue and could someone please explain why this is happening? 使用什么模式来解决此问题,有人可以解释为什么会这样吗? I'm coming from Java and clearly, things are different there, heh. 我来自Java,显然那里的情况有所不同,呵呵。 I would expect the parent component to be able to access everything that happens into the child component, every variable you expose and the other way around because they are working on the SAME(?) object. 我希望父组件能够访问子组件中发生的所有事情,您公开的每个变量以及相反的方法,因为它们正在处理SAME(?)对象。

Thanks in advance and have a nice day! 在此先感谢您,祝您愉快!

You should be using input to your child component and ViewChildren to have array of components as below 您应该使用子组件和ViewChildren的输入,以具有如下所示的组件数组

import {Component, OnInit} from "@angular/core";
@Component({
  selector: 'tab',
  template: `
            <h1>{{tab?.title}} / {{tab?.deletable}}</h1>
`,
})
export class Tab implements OnInit{
@Input() tab:TabModel;

}

In your App 在您的应用中

@Component({
  selector: 'my-app',
  template: `
            <div *ngFor="let tab of tabs let i=index">
                <tab [tab]="tab"></tab>
            <button (click)="removeTab(i)">REMOVE</button>
            </div>
            <button (click)="addTab()">Add new tab</button>

`,
})
export class App implements AfterViewInit {
    @ViewChildren(Tab) tabs: QueryList<Tab>;
    tabs: Array<TabModel> = [
                {id : 1 , title: 'a',deletable:true},
                {id : 3 , title: 'v',deletable:false},
                {id : 5 , title: 'b', deletable: true}
            ];
    ngAfterViewInit(): void {
    }
    removeTab(i){
        //remove the item from the array using splice
        this.tabs.splice(..)
    }
}

Yup, what I was missing was that the Tab component isn't the same as doing new Tab() . 是的,我所缺少的是Tab组件与执行new Tab() <tab> creates a component while new Tab()` creates a new instance of the class. <tab> creates a component while new Tab()`创建该类的新实例。 So I was trying to access two different things. 所以我试图访问两个不同的东西。

What I ended up doing is this: Crate a TabData object that holds stuff like title, deletable or any other info and inject it into the component using @Input and just control info thru that. 我最终要做的是:创建一个包含标题,可删除内容或任何其他信息之类的TabData对象,然后使用@Input将其注入到组件中,然后通过它控制信息。 Something like this: 像这样:

@Component({
  selector: 'tab',
  providers: [TabsService],
  template: `
<products (totalUpdated)="processDeletable($event)"></products>
`,
})
export class Tab {

  @ViewChildren(Products)
  public products: QueryList<Products>;
  @Input() tabData:TabData;

  processDeletable(total: number) {
    this.tabData.deletable = total > 0 ? false : true;
    console.log("TAB " + this.tabData.title + " IS DELETABLE? " + this.tabData.deletable);
  }

}

You live and learn 你生活和学习

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

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