Angular 2在第一次完成时进行第二次发射

时间:2016-12-05 12:12:37

标签: angularjs angular typescript

我们已经开始从ng1迁移到ng2,但我不了解如何升级我的按钮组件。例如: 在角度1中,我可以在组件内部传递一个promise并等待响应,如:

class ButtonController {
   click: () => Promise<any>;
   form: SomeForm;

   onClick(): void {
      this.click().then(() => {
         this.form.doSomething();
      });
   }
}

export const ButtonComponent = {
   templateUrl: 'button-component.template.html',
   controller: ButtonController,
   controllerAs: 'vm',
   require: '^form',
   bindings: {
      click: '&'
   }
});

但是,如何使用@Output和EventEmitter在角度2中实现此目的?我已经使用@Input,组件回调和ButtonComponent与FormComponent之间的服务实现了这一点,但我确定它完全错了。对任何帮助都会感到高兴。感谢。

angular 2 code:

登录up.template.html

// content
<ab-form [uFormGroup]="signUpForm">
   //content
   <ab-button [uClick]="onClick"></ab-button>
</ab-form>

登录up.component.ts

export class SignUpComponent {
   onClick = () => {
      //do something async
   }
}

form.component.ts

@Component({
   selector: "ab-form",
   template: require("./form.template.html"),
   providers: [
      FormService
   ]
})
export class FormComponent {
   @Input() uFormGroup: FormGroup;

   constructor(
      private formService: FormService
   ) {
      this.formService.buttonClicked$.subscribe((fn) => {
         this.uFormGroup['submitted'] = true;

         if (this.uFormGroup.invlaid) {
            return this.formService.endSubmittingForm();
         }

         this.formService.startSubmittingForm();
         // resolve if function is not a promise
         Promise.resolve(fn()).then(() => {
            this.formService.endSubmittingForm();
         });
      });
   }
}

button.component.ts

export class ButtonComponent {
   submitting = false;

   constructor(
      private formService: FormService
   ) {
      this.formService.formSubmitting$.subscribe(() => {
         this.submitting = true;
      });

      this.formService.formSubmitted$.subscribe(() => {
         this.submitting = false;
      });
   }

   onClick(): void {
      this.formService.buttonClick(this.uClick);
   }
}

form.service.ts

export class FormService {
    private buttonClickedSource = new Subject<Function>();
    private formSubmittingSource = new Subject<void>();
    private formSubmitedSource = new Subject<void>();

    buttonClicked$ = this.buttonClickedSource.asObservable();
    formSubmitting$ = this.formSubmittingSource.asObservable();
    formSubmited$ = this.formSubmitedSource.asObservable();

    buttonClick(fn: Function): void {
        this.buttonClickedSource.next(fn);
    }

    startSubmittingForm(): void {
        this.formSubmittingSource.next();
    }

    endSubmittingForm(): void {
        this.formSubmitedSource.next();
    }
}

2 个答案:

答案 0 :(得分:0)

您可以创建简单的组件输入和输出,如下所示:

@Component({
    selector: 'myButton',
    template: '<button (click)="buttonAction()">{{label}}</button>',
    inputs: ['label']
}) 
export class MyButton {
    @Input()
    label:string;

    @Output() 
    myButtonClick = new EventEmitter<any>();

    ...

    buttonAction() {
        this.tableButtonClick.emit("some value")
    }
}

然后在你的模板中使用它:

 <myButton [label]="sample"
     (myButtonClick)="handleMyButtonClick($event)">
 </myButton>

$ event将是字符串“some value”,但您可以使用任何您喜欢的对象

答案 1 :(得分:0)

您可以使用Observer

执行与Angular 1相同的操作
onClick(): void {
  this.formService.buttonClick().subscribe(() => {
    // You reach this when buttonClick is async terminated
    // like your then() in your Angular 1 code
    this.uClick()
    ...
  });
}

在您的FormService中,您将返回Observable:

buttonClick(): Observable<any> {
    return this.buttonClicked$;
}