Angular: Как заставить мой компонент изменять значение одного из свойств его родителя - PullRequest
0 голосов
/ 10 сентября 2018

Я работаю с Кендо в Angular некоторое время, и меня кое-что заинтриговало. Многие компоненты Kendo имеют свойство, называемое value. Это свойство связано со свойством моего компонента (родительского элемента) следующим образом:

<kendo-numerictextbox [value]="quantity">
</kendo-numerictextbox>

Здесь quantity - это свойство моего компонента. Интересно то, что каждый раз, когда пользователь нажимает на числовое текстовое поле, компонент Kendo обновляет свойство моего компонента. Я пытался повторить то же поведение с моими компонентами, конкретно, я экспериментировал с @HostBinding, но вместо того, чтобы использоваться с директивой, я использую его с компонентом:

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent {
  @HostBinding('title') title;

  constructor() { }    
}

Еще одна вещь, которую я попробовал, - это инъекция родителя ребенку.

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent {
  constructor(@Host() public parent: AppComponent) { }
}

В этом случае, да, у меня есть доступ к родительским свойствам, но это означает, что дочерний компонент должен знать тип своего родителя.

Вот ссылка на стекаблиц.

Честно говоря, я понятия не имею, как это сделать. Есть идеи?

РЕДАКТИРОВАТЬ: Пожалуйста, обратите внимание, что я спрашиваю о том, как я могу повторить то же поведение, что и компоненты Kendo в отношении их свойства value. Я не прошу обходного пути с использованием общих служб.

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

вы можете использовать BehaviorSubject для достижения этого (или EventEmitter aswell). Я использовал первый.

Добавить услугу:

@Injectable()
export class AppService{
    private $change = new BehaviorSubject<string>(null);
    closeEvent = this.$change.asObservable();

    public changeText(){
      this.$change.next("Child changed title");
    }
}

дочерний компонент:

import { Component, Host, HostBinding } from '@angular/core';
import { AppComponent } from '../app.component';
import { AppService } from '../app.service';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent {
  @HostBinding('title') title;

  constructor(@Host() public parent: AppComponent, private serivce: AppService) { }
  public magic(){
    this.serivce.changeText();
  }
}

родительский компонент

import { Component } from '@angular/core';
import { AppService} from './app.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  title = 'Title from parent';

  constructor(private service: AppService){
    this.service.closeEvent
    .subscribe( evt => {
      if(!!evt){
        this.title = evt;
      }
    })
  }
}

app module

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { AppService } from './app.service';
import { ChildComponent } from './child/child.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, ChildComponent ],
  providers: [AppService],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

Когда вы нажимаете кнопку «Нажми меня», текст изменяется после изменения вашего дочернего компонента

0 голосов
/ 10 сентября 2018

Похоже, это должно быть то, что вы ищете.

Сначала вам нужно @Input(), которое будет принимать текущее значение от родителя. Кроме того, вам нужно @Output(), которое выдаст новое значение.

Например

parent.html

<kendo-numerictextbox [(value)]="quantity">
</kendo-numerictextbox>

child.ts

@Input() value: string;
@Output() valueChange = new EventEmiter<string> = new EventEmiter<string>();

public someEvent(newString: string) {
 this.valueChange.emit(newString)
}
...