Angular 更改子组件变量时更新父组件

Angular 更改子组件变量时更新父组件,angular,angular2-components,Angular,Angular2 Components,例如,我有一个来自服务的名为totalQuantity的变量 我有一个子组件,它只在用户登录时初始化变量 这是子组件 import { Component, OnInit, Output, EventEmitter } from '@angular/core'; import { CartService } from '../cart'; @Component({ selector: 'landing', templateUrl: './landing.component.h

例如,我有一个来自服务的名为totalQuantity的变量

我有一个子组件,它只在用户登录时初始化变量

这是子组件

import { Component, OnInit, Output, EventEmitter } from '@angular/core';

import { CartService } from '../cart';

@Component({
    selector: 'landing',
    templateUrl: './landing.component.html'
})

export class LandingComponent implements OnInit{
    @Output() homeChanged = new EventEmitter;

    constructor(private _cartService: CartService){}

    ngOnInit(){
        this._cartService.getCartItems(localStorage.getItem('currentUserId'))
            .subscribe((cart) => {
                this.homeChanged.emit(this._cartService.totalQuantity);
                console.log(this._cartService.totalQuantity);
            },
            err => console.log(err));
    }
}
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { loginStatusChanged } from './auth.guard';
import { CartService } from './cart';
import { UserService } from './user';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
  title = 'app works!';

  loginStatus: boolean;

  constructor(private _cartService: CartService, private _userService: UserService, private _router: Router){}

  onLogout(){
    this._userService.logout();
    loginStatusChanged.next(false);
    this._router.navigate(['/login']);
  }

  ngOnInit(){
    this.onLogout();
    loginStatusChanged.subscribe(status => this.loginStatus = status);
  }
}
如您所见,我有一个名为homeChanged的@Output变量,当子组件初始化时,它将发出totalQuantity。如果用户登录,我需要在我的父组件中显示它,因为这是navbar上购物车显示的唯一时间

这是我的父组件

import { Component, OnInit, Output, EventEmitter } from '@angular/core';

import { CartService } from '../cart';

@Component({
    selector: 'landing',
    templateUrl: './landing.component.html'
})

export class LandingComponent implements OnInit{
    @Output() homeChanged = new EventEmitter;

    constructor(private _cartService: CartService){}

    ngOnInit(){
        this._cartService.getCartItems(localStorage.getItem('currentUserId'))
            .subscribe((cart) => {
                this.homeChanged.emit(this._cartService.totalQuantity);
                console.log(this._cartService.totalQuantity);
            },
            err => console.log(err));
    }
}
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { loginStatusChanged } from './auth.guard';
import { CartService } from './cart';
import { UserService } from './user';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
  title = 'app works!';

  loginStatus: boolean;

  constructor(private _cartService: CartService, private _userService: UserService, private _router: Router){}

  onLogout(){
    this._userService.logout();
    loginStatusChanged.next(false);
    this._router.navigate(['/login']);
  }

  ngOnInit(){
    this.onLogout();
    loginStatusChanged.subscribe(status => this.loginStatus = status);
  }
}
父组件HTML,我将在其中放置
totalQuantity

<ul class="navigation">
  <li class="logo"><img src="assets/images/nav_logo.png"></li>
  <li><a routerLink="/home" routerLinkActive="active">Home</a></li>
  <li><a routerLink="/mainproducts" routerLinkActive="active">Products</a></li>
  <li *ngIf="loginStatus"><a href="http://localhost:3000">Designer</a></li>
  <li *ngIf="loginStatus"><a routerLink="/cart" routerLinkActive="active">Cart({{totalQuantity}})</a></li>
  <li *ngIf="!loginStatus"><a routerLink="/login" routerLinkActive="active">Login</a></li>
  <li *ngIf="loginStatus" class="dropdown"><a (click)="onLogout()">Logout</a></li>

</ul>

<router-outlet></router-outlet>
  • 购物车({{totalQuantity}) 登录 注销

有人能帮我在购物车旁边的导航栏上显示总数量吗

以下是如何从子组件更新父组件

        @Component({
          selector: 'child-selector',
          template: 'child.component.html'
        })
        export class ChildComponent {  
          @output() notify: EventEmitter<string> = new EventEmitter<string>();

          onClick() {
            this.notify.emit('Click from nested component');
          }
        }




        /* parent.conponent.html */
        <div>  
          <h1>I'm a container component</h1>
          <child-selector (notify)='onNotify($event)></child-selector>
        </div>  




        @Component({
          selector: 'parent-selector',
          template: 'parent.component.html',
          directives: [ChildComponent]
        })
        export class ParentComponent {  
          onNotify(message:string):void {
            alert(message);
          }
        }
@组件({
选择器:“子选择器”,
模板:“child.component.html”
})
导出类ChildComponent{
@output()notify:EventEmitter=neweventemitter();
onClick(){
this.notify.emit('Click from nested component');
}
}
/*parent.conponent.html*/
我是一个容器组件

以下是如何从子组件更新父组件

        @Component({
          selector: 'child-selector',
          template: 'child.component.html'
        })
        export class ChildComponent {  
          @output() notify: EventEmitter<string> = new EventEmitter<string>();

          onClick() {
            this.notify.emit('Click from nested component');
          }
        }




        /* parent.conponent.html */
        <div>  
          <h1>I'm a container component</h1>
          <child-selector (notify)='onNotify($event)></child-selector>
        </div>  




        @Component({
          selector: 'parent-selector',
          template: 'parent.component.html',
          directives: [ChildComponent]
        })
        export class ParentComponent {  
          onNotify(message:string):void {
            alert(message);
          }
        }
@组件({
选择器:“子选择器”,
模板:“child.component.html”
})
导出类ChildComponent{
@output()notify:EventEmitter=neweventemitter();
onClick(){
this.notify.emit('Click from nested component');
}
}
/*parent.conponent.html*/
我是一个容器组件

您可以使用主题,如下所示:

  AppComponent.returned.subscribe(res => {
     console.log('change happened!');
     console.log(res) // you have your passed value here
  });
在您的家长中:

public static returned: Subject<any> = new Subject();
在您的childcomponent中,您需要在其中添加这个,作为您想要的参数,这里我们只传递一个字符串

AppComponent.returned.next('test'); // pass whatever you need

编辑:仅当您的子组件不在其他管线后面时,输出才起作用。因此,在您的情况下,您不能使用输出。

您可以使用主题,例如:

  AppComponent.returned.subscribe(res => {
     console.log('change happened!');
     console.log(res) // you have your passed value here
  });
在您的家长中:

public static returned: Subject<any> = new Subject();
在您的childcomponent中,您需要在其中添加这个,作为您想要的参数,这里我们只传递一个字符串

AppComponent.returned.next('test'); // pass whatever you need


编辑:仅当您的子组件不在其他管线后面时,输出才起作用。因此,在您的情况下,您不能使用输出。

您在哪里设置属性我在AppComponent中看不到它的设置?您在哪里使用登录组件?您需要类似于
无的东西。我使用路由器插座来导航。有没有办法更新购物车?你在哪里设置你的属性?我在AppComponent中看不到它的设置?你在哪里使用登录组件?您需要类似于
无的东西。我使用路由器插座来导航。有没有办法更新购物车?我正在使用路由器出口进行导航,因此我没有子组件的选择器。好的,但您在Appcomponent中注入了cartService,因此您可以在用户登录后调用此服务并更新totalItem属性。只是一个值得尝试的猜测,但问题是,应用程序组件将在应用程序启动时初始化,即使用户未登录。如果有任何方法可以在用户登录后重新初始化或更新应用程序组件的UI,这将非常有帮助。如果我理解正确,则很抱歉,即使用户未登录,应用程序启动时应用程序组件也会初始化。但用户必须在某个地方登录我们需要做的事情,当用户登录时,我们需要调用cartservice。我想如果你在登录服务中有发射器,当用户登录时它会更新,那么你可以使用应用程序内组件。我的问题是我没有选择器,因为我使用的是路由器出口。若父组件中并没有子选择器,我不知道该放在哪里。正如我的代码中所述,app.component仅由导航栏和路由器出口组成。我使用路由器出口进行导航,因此我没有子组件的选择器。好的,但您在Appcomponent中注入了cartService,因此您可以调用此服务,并在用户登录后更新totalItem属性。只是一个值得尝试的猜测,但问题是,应用程序组件将在应用程序启动时初始化,即使用户未登录。如果有任何方法可以在用户登录后重新初始化或更新应用程序组件的UI,这将非常有帮助。如果我理解正确,则很抱歉,即使用户未登录,应用程序启动时应用程序组件也会初始化。但用户必须在某个地方登录我们需要做的事情,当用户登录时,我们需要调用cartservice。我想如果你在登录服务中有发射器,当用户登录时它会更新,那么你可以使用应用程序内组件。我的问题是我没有选择器,因为我使用的是路由器出口。若父组件中并没有子选择器,我不知道该放在哪里。如我的代码所述,app.component仅由导航栏和路由器插座组成。谢谢!你救了我的命!谢谢你救了我的命!