угловая функция при нажатии на рекурсивный дочерний элемент - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь вызвать функцию, сгенерированную рекурсивным декоратором @Input.Проблема в том, что событие (click) не влияет на детей.Только родительские щелчки элементов генерируют событие.

import { Component, Input, Output, EventEmitter } from '@angular/core';
import {AdminCategory} from './admin-category.component'

@Component({
  selector: 'categories',
  template: `
     <div *ngFor="let cat of categories">
      <ul>
       <li>
         <span (click)="addCategory(cat)">{{cat.name}}</span>
         <categories [categories]="cat.children" </categories>
       </li>
      </ul>
    </div>
  `,
})
export class TreeView {
  @Input() categories;
  @Output() category: EventEmitter<AdminCategory> = new EventEmitter<AdminCategory>();

  addCategory(category: AdminCategory){
    this.category.emit(category);
  }
}

Я нашел где-то здесь на SO (к сожалению, не могу найти ссылку сейчас), что добавление ($event) должно решить проблему, поэтому я попробовал это:

import { Component, Input, Output, EventEmitter } from '@angular/core';
import {AdminCategory} from './admin-category.component'

@Component({
  selector: 'categories',
  template: `
     <div *ngFor="let cat of categories">
      <ul>
       <li>
         <span (click)="addCategory(cat)">{{cat.name}}</span>
         <categories [categories]="cat.children" (clickEvent)="onClickChild($event)"> asd</categories>
       </li>
      </ul>
    </div>
  `,
})
export class TreeView {
  @Input() categories;
  @Output() category: EventEmitter<AdminCategory> = new EventEmitter<AdminCategory>();

  addCategory(category: AdminCategory){
    this.category.emit(category);
  }

  onClickChild(event){
    console.log("asdas");
    this.category.emit(event);
  }
}

Но без каких-либо результатов console.log("asdas"); никогда не происходит.Кто-нибудь знает причину этой проблемы?Что я делаю не так?

1 Ответ

0 голосов
/ 25 апреля 2018

Свойство Output в директивах или компонентах переносит ответственность за управление изменением, вызванным событием, на родительский элемент посредством обратного вызова. В этом случае вызов функции начинается на узле дерева через Output (click) и вызывает "рекурсивно" onClickChild с тем же методом Output / callback, пока не достигнет корня дерева. В angular этот обратный вызов является шаблонным выражением .

Хотя все вышесказанное ничего не стоит, если вы используете централизованный метод управления данными, такой как redux. Исходя из моего опыта, я рекомендую это, поскольку вам не нужно делать все вышеперечисленное. Только

import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Store } from '@ngrx/store';

import { AppState } from '../store';
import { AdminCategory } from './admin-category.component';
import { AddCategoryAction } from './admin-category.actions';

@Component({
  selector: 'categories',
  template: `
     <div *ngFor="let cat of categories">
      <ul>
       <li>
         <span (click)="addCategory(cat)">{{cat.name}}</span>
         <categories [categories]="cat.children"> asd</categories>
       </li>
      </ul>
    </div>
  `,
})
export class TreeView {
  @Input() categories;

  contructor(private store: Store<AppState>) {}
  addCategory(category: AdminCategory){
    this.store.dispatch(new AddCategoryAction(category));
  }
}

Я прилагаю документацию и пример приложения . Как построить AddCategoryAction, редуктор

import { CategoryActionTypes, CategoryActionsUnion } from './category.actions';
import { EMPTY_ARR } from '../empties';

export type CategoryState = CategoryModel[];


export const CATEGORY_INIT: CategoryState = EMPTY_ARR;

export function reducer(state: CategoryState  = CATEGORY_INIT, action: CategoryActionsUnion): State {
  switch(action.type) {
    case CategoryActionTypes.ADD: {
      return state.concat(action.payload);
    }

    case CategoryActionTypes.RESET: {
      return CategoryInit;
    }

    case CategoryActionTypes.ANOTHER: {...

    default: {
      return state;
    }
  }
}

И импорт в AppModule

import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { categoryReducer } from './category';

@NgModule({
  imports: [BrowserModule, StoreModule.forRoot({ category: categoryReducer })],
})
export class AppModule {}

И вам не нужно пересекать дерево, чтобы изменить или проверить состояние

Подробнее о преимуществах можно узнать здесь . Наслаждаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...