user3613162
user3613162

Reputation: 229

Dynamically create and add new component on button click in Angular Dart

I have a problem very similar to the one asked here How to add a component programatically in Angular.Dart?. I am using Angular Dart and have a task bar component that I want to fill with a list of task components. I would like a new task component to be added when a button is pressed. Here is the code I currently have.

task_bar_component.html

<ul id="taskList" class="taskBar-items">
    <li ng-repeat="task in taskbarCmp.tasks">
        {{task}}
    </li>
</ul>

task_bar_component.dart

@Component(
    visibility: Directive.CHILDREN_VISIBILITY,
    selector: 'taskbar',
    templateUrl: '../lib/components/taskbar_component.html',
    publishAs: 'taskbarCmp',
    useShadowDom: false)

class TaskBarComponent {
  List tasks;

  TaskBarComponent() {
    tasks = new List();
  }

  void addTask() {
    var newTask = new TaskComponent();
    tasks.add(newTask);
  }
}

task_component.dart

@Component(
    visibility: Directive.CHILDREN_VISIBILITY,
    selector: 'task',
    templateUrl: '../lib/components/task_component.html',
    publishAs: 'taskCmp',
    useShadowDom: false)

class TaskComponent {
  bool _collapsed = true;
  int _lopCount = 0;
  int _geoCount = 0;
  int _volume = 1;
  String id;

  TaskComponent() {
    Collapse.use();
  }
}

This code currently adds an "Instance of 'TaskComponent'" to the html on the button click, but it does not contain the actual task_component.html. I tried using the ShadowRootAware from the solution in the previous question but am not sure how onShadowRoot gets called when the button is pressed. I also tried to use the directive solution that was suggested in that post as well and had the same issue, not being able to create the component when the button is pressed. ANy suggestions would be greatly appreciated.

Upvotes: 2

Views: 2071

Answers (2)

Vink
Vink

Reputation: 1277

Actually, your code doesn't work because

{{task}}

don't call the view of your component, it try to display the object directly, and it's not what you want.

To get the behavior that you want, you need do more like that :

class Task {
   // What you want in your task
}

@Component(
   visibility: Directive.CHILDREN_VISIBILITY,
   selector: 'task',
   templateUrl: '../lib/components/task_component.html',
   publishAs: 'taskCmp',
   useShadowDom: false)

class TaskComponent {
  @NgTwoWay('task')
  Task task;
  // What you want for you task view

  TaskComponent() {
    Collapse.use();
  }
}


// task bar
class TaskBarComponent {
  List<Task> tasks;

  TaskBarComponent() {
    tasks = new List();
  }

  void addTask() {
     var newTask = new Task();
     tasks.add(newTask);
  }
}

and in your html :

<ul id="taskList" class="taskBar-items">
   <li ng-repeat="task in taskbarCmp.tasks">
      <task task="task"></task>
   </li>
</ul>

In this case, you have perfectly separate the logic from the view and get the modularity of Angular Component

Upvotes: 2

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657821

I would suggest more something like

<ul id="taskList" class="taskBar-items">
    <li ng-repeat="task in taskbarCmp.tasks">
        <task id={{task.id}}><div class="task-caption">{{task.caption}}</div><div class="task-description>{{task.description}}</div></task>
    </li>
</ul>

and your collection of tasks in your component holds instances of Task classes with the data attributes that define your task (like the id, caption and text attributes I used in the example).

Upvotes: 0

Related Questions