【问题标题】:Shopping cart counter in AngularJS 2AngularJS 2 中的购物车计数器
【发布时间】:2016-12-23 22:37:29
【问题描述】:

我正在做一个项目,我需要一个带柜台的购物车图标。我正在使用 AngularJS 2,但被卡在了某个地方。我需要一个购物车图标,标题中有一个柜台。当有人从购物车中删除商品时,我希望标题中的数字减少。因为标题和购物车是 2 个不同的组件,并且都有不同的控制器,所以我不明白如何通知标题已经从购物车中删除了一个项目。

亲切的问候

更新: 我自己找到了解决方案,通过使用共享服务可以实现。 您只需要在服务中声明一个名为“数量”的变量,将服务注入到标头组件的构造函数中,并在您使用“yourService.quantity”的标头模板中。

【问题讨论】:

  • Angular2 不是 angularjs。修复你的标签。另外,使用服务。创建一个主题(如果是打字稿)并通过它发送一个信号。

标签: angular


【解决方案1】:

您需要使用EventEmitter API 和@Output 装饰器。

假设我们有一个父 Component 并在我们想要调用的类上设置一个名为 myValueChange 的函数,当我们将它绑定到一个名为 CounterComponent’s 的组件时:

// app.component.ts
import {Component} from 'angular2/core';
import {CounterComponent} from './counter.component';

@Component({
  selector: 'my-app',
  styles: [`
    .app {
      display: block;
      text-align: center;
      padding: 25px;
      background: #f5f5f5;
    }
  `],
  template: `
    <div class="app">
      <counter [counterValue]="myValue"></counter>
    </div>
  `,
  directives: [CounterComponent]
})
export class AppComponent {
  public myValue:number = 2;
  myValueChange(event) {
    console.log(event);
  }
}

AppComponent 类中,我们声明了myValueChange,它接受事件作为参数。接下来我们需要在&lt;counter&gt; 组件上创建一个自定义属性名称来挂钩这个函数,我们称之为counterChange

// app.component.ts
import {Component} from 'angular2/core';
import {CounterComponent} from './counter.component';

@Component({
  selector: 'my-app',
  styles: [`
    .app {
      display: block;
      text-align: center;
      padding: 25px;
      background: #f5f5f5;
    }
  `],
  template: `
    <div class="app">
      <counter [counterValue]="myValue" (counterChange)="myValueChange($event);"></counter>
    </div>
  `,
  directives: [CounterComponent]
})
export class AppComponent {
  public myValue:number = 2;
  myValueChange(event) {
    console.log(event);
  }
}

注意我们是如何使用 (counterChange) 和括号括起来的,这告诉 Angular 这是一个事件绑定,类似于(click)。现在我们需要在 CounterComponent 中镜像这个 API。

 // counter.component.ts
 import {Component, Input, Output, EventEmitter} from 'angular2/core';

 @Component({
   selector: 'counter',
   styles: [`
     // omitted
   `],
   template: `
     // omitted
   `
 })
 export class CounterComponent {
   @Input() counterValue = 0;
   @Output() counterChange = new EventEmitter();
   increment() {
     this.counterValue++;
     this.counterChange.emit({
       value: this.counterValue
     })
   }
   decrement() {
     this.counterValue--;
     this.counterChange.emit({
       value: this.counterValue
     })
   }
 }

注意@Output counterChange 是如何设置为EventEmitter 的新实例的,这个@Output 装饰器使counterChange 属性可用作事件绑定,就像我们在上面的模板(counterChange) 中看到的那样。

几乎在那里,我们想告诉父组件counterChange 事件发生在子Component 实际更新值时,我们知道这发生在点击事件上。让我们在那里发出一个事件,因为这似乎是一个合乎逻辑的地方:

// counter.component.ts
...
export class CounterComponent {
  @Input() counterValue = 0;
  @Output() counterChange = new EventEmitter();
  increment() {
    this.counterValue++;
    this.counterChange.emit({
      value: this.counterValue
    })
  }
  decrement() {
    this.counterValue--;
    this.counterChange.emit({
      value: this.counterValue
    })
  }
}

请注意,我们正在发出一个带有 value 属性的Object,您不必这样做,但是在父级的回调中使用事件时它看起来更好(event.value 更明确)。

我们的父组件现在可以获取 $event 对象,因为我们已使用 (counterChange)="myValueChange($event);" 将其传递到模板中。

// app.component.ts
...
export class AppComponent {
  public myValue:number = 2;
  myValueChange(event) {
    // result: { value: <number> }
    console.log(event);
  }
}

就是这样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    • 2018-07-04
    • 2020-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多