Angular2: нет провайдера для String! (потомок -> Строка) в [Массив в родительском

Я создаю базовое приложение Todo в angular2, когда я нажимаю кнопку «Добавить», чтобы отправить данные от родителя к дочернему элементу, используя ввод, я получаю «Нет провайдера для строки»! (child->string), а данные не отображаются, отображается только кнопка в дочернем классе, что это значит

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

@Component({
selector : 'parent-component',
directives : [child],
template : `
<h1 class= "text-center">ToDo App</h1>
<div class = "form-group">
<lable>Task</lable>
<input type = "text" class = "form-control" #task>
<lable>Detail</lable>
<input type = "text" class = "form-control" #detail >
<button type = "submit" class  = "btn btn-default" 
(click) = "addtask(task,    detail)">Add Task</button>


<child-component *ngFor = "#todo of Array" [taskobject] = "todo">
Loading... </child-component>
</div>

`
})
class parent{
//taskobj : {task : string, details : string, id:  number};
Array : child[];
id : number;

constructor(){

    //i want this to initialize asa parent create
    this.Array = [];
}

addtask(task : HTMLInputElement, detail : HTMLInputElement){
    // this.taskobj.task= task.value;
    // this.taskobj.details = detail.value;
   this.id = Date.now();
    // this.array.push();

    this.Array.push(new child(task.value, detail.value, this.id ));
    console.log(Array)
    task.value = '';
    detail.value = '';

}

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

@Component({

selector : 'child-component',
inputs : ['taskobject'],
//outputs : ['objectsend'],
template : `
  {{taskobject.task}}
  {{taskobject.details}}
  <button type = "button" class = "btn btn-default" 
  (click) = "deletetask()">Delete</button>
  <button type = "button" class = "btn btn-defualt" 
  (click) = "updatetask()">Update</button>

  `
  })
class child{

//we are creating a instance just as configured as child component 
task : string;
detals : string;
id : number;
//array : any[];

constructor(task : string, detail : string, id : number){
    this.task = task;
    this.detals = detail;
    this.id = id;
}

}

person blackHawk    schedule 02.02.2016    source источник
comment
Что вы ожидаете передать конструктору class child?   -  person Günter Zöchbauer    schedule 02.02.2016
comment
задача, детали задачи от родителя, а также уникальный идентификатор для конкретной задачи   -  person blackHawk    schedule 02.02.2016


Ответы (2)


Вы получили ошибку, так как Angular2 создает экземпляр класса child самостоятельно и пытается внедрить в него параметры, которые вы определяете на уровне конструктора. Для них нет связанного провайдера...

В противном случае, если вы хотите ссылаться на дочерние компоненты из родительских, вы можете использовать декоратор @ViewChild для ссылки на дочерний компонент из родительского путем инъекции:

import { Component, ViewChild } from 'angular2/core';  

(...)

@Component({
  selector: 'my-app',
  template: `
    <h1>My First Angular 2 App</h1>
    <child></child>
    <button (click)="submit()">Submit</button>
  `,
  directives:[App]
})
export class AppComponent { 
  @ViewChild(SearchBar) searchBar:SearchBar;

  (...)

  someOtherMethod() {
    this.searchBar.someMethod();
  }
}

Вот обновленный планкр: http://plnkr.co/edit/mrVK2j3hJQ04n8vlXLXt?p=preview.

Вы можете заметить, что можно также использовать декоратор параметра @Query:

export class AppComponent { 
  constructor(@Query(SearchBar) children:QueryList<SearchBar>) {
    this.childcmp = children.first();
  }

  (...)
}

Надеюсь, это поможет вам, Тьерри.

person Thierry Templier    schedule 02.02.2016
comment
Вы имеете в виду, что я не определил входные данные в дочернем компоненте? - person blackHawk; 02.02.2016
comment
О, извините, я пропустил ваш атрибут inputs ... Раньше я использовал декоратор для этого ;-) Я соответственно обновил свой ответ - person Thierry Templier; 02.02.2016
comment
Ваша проблема связана с конструктором вашего дочернего компонента и тем фактом, что вы создаете экземпляр класса child вручную... - person Thierry Templier; 02.02.2016
comment
Вручную я создаю дочерний класс, как? - person blackHawk; 02.02.2016
comment
Здесь: this.Array.push(new child(task.value, detail.value, this.id ));, нет? ;-) - person Thierry Templier; 02.02.2016
comment
О да :) так что лучше вместо этого, я сделал это, чтобы вставленный объект был объектом дочернего элемента в массиве - person blackHawk; 02.02.2016
comment
На самом деле использование ngFor и использование соответствующего элемента в качестве параметра подкомпонента сделает то же самое ;-) - person Thierry Templier; 02.02.2016
comment
Без массива? Не могли бы вы plunkr ;) - person blackHawk; 02.02.2016
comment
Вот планкр: plnkr.co/edit/0AZMqlu2gamjj1zTZbaV?p=preview ;- ) Обратите внимание на использование метода concat вместо push для запуска обнаружения изменений Angular2 (stackoverflow.com/questions/35076907/ - также можно использовать slice) - person Thierry Templier; 02.02.2016
comment
та же проблема: ИСКЛЮЧЕНИЕ: нет провайдера для String! (дочерний объект -> строка) в [Arrayobj в родительском] (имя изменено с Array на Arrayobj) - person blackHawk; 02.02.2016
comment
В plunkr, который я вам предоставил? Судя по сообщению об ошибке, я думаю, что в конструкторе компонента child остались какие-то параметры... - person Thierry Templier; 02.02.2016
comment
plnkr.co/edit/KNhred?p=info вот мой планкр, ошибка исчезло, но не отображается задача или описание, отображаются только кнопки обновления и удаления - person blackHawk; 02.02.2016
comment
Я предполагаю, что это проблема, связанная с обнаружением изменений в Angular2. На самом деле вам нужно обновить всю ссылку вашего массива. Обновления в нем не будут обнаружены Angular. Вы можете посмотреть на мой plunkr в разделе addtask: я использовал метод concat вместо метода push. Чтобы удалить, вам нужно использовать метод slice... Надеюсь, это понятно. Подробнее см. в этом ответе: stackoverflow.com/questions/35076907/ - person Thierry Templier; 02.02.2016
comment
Я думаю, что @Thierry не очень хорошая идея помещать все, что ожидается, должно инициализироваться в конструкторе класса определения (потому что я не знаю, когда его инициализируют: P), поэтому я опустошил конструктор, теперь, если я беру данные из формы, это придет для меня в этой форме input name = tasks #task class = form-control , что означает весь входной тег, а также локальная переменная класса заставляет его быть типом входного элемента, когда я делаю this.task = задача в функции addtask, потому что она не может назначить тип элемента html в строку - person blackHawk; 03.02.2016
comment
О, я забыл task.value :D - person blackHawk; 03.02.2016

Параметры конструктора разрешаются из поставщиков DI, указанных в bootstrap(AppComponent, [SomeProvider, SomeOtherProvider, ...]);

Входы назначаются автоматически, но только после вызова жизненного цикла ngOnInit().

@Component({
  selector : 'child-component',
  inputs : ['taskobject'],
  //outputs : ['objectsend'],
  template : `
    {{taskobject?.task}}
    <!-- use the safe-navigation operator ?. to avoid errors 
      when `taskobject` is not yet set
    -->
    {{taskobject?.details}}
    <button type = "button" class = "btn btn-default" 
    (click) = "deletetask()">Delete</button>
    <button type = "button" class = "btn btn-defualt" 
    (click) = "updatetask()">Update</button>
    `
})
class child {
  //we are creating a instance just as configured as child component 
  taskobject: any;
  task : string;
  detals : string;
  id : number;
  //array : any[];

  constructor() {
  }

  // when this callback is called the 
  // `taskobject` (from `inputs : ['taskobject'],`) 
  // is initialized 
  ngOnInit() {
    this.task = taskobject.task;
    this.detals = taskobject.detail;
    this.id = taskobject.id;
  }
}
person Günter Zöchbauer    schedule 02.02.2016
comment
Не могли бы вы предоставить полезную ссылку, чтобы понять это предложение или немного объяснить здесь, параметры конструктора разрешаются из поставщиков DI, указанных в начальной загрузке (AppComponent, [SomeProvider, SomeOtherProvider, ...]); - person blackHawk; 02.02.2016
comment
Я знаю, что данные, поступающие от входных данных, доступны для просмотра/шаблона дочернего класса (в моем случае объект задачи), как я могу научить дочерний класс определения объекту задачи, поступающему от родителя через ввод, - person blackHawk; 02.02.2016
comment
Это то, что делает «вход». Вы должны передавать входные данные, используя привязку шаблона, например <child-component [someInput]="someParentValue"> - person Günter Zöchbauer; 02.02.2016