0

I have a rather large list with todo items for which I want to add in place editing for:

  [ ] first todo
  [ ] second todo
  [ ] third todo

after clicking on the second todo, the text of the second todo can be edited but you can also set some properties on the todo:

  [ ] first todo
 -----------------------------------------------------------
| [ ] second todo__________________                         |
|     due: __/__/____                                       |
|     assigned: ______________                              |
|                                                           |
|     [save] [cancel]                                       |
 -----------------------------------------------------------
  [ ] third todo

Now I can do something like:

<div ng-repeat="todo in todos">
  <div ng-show="!doedit">
    <input type="checkbox"> <a href="" ng-click="doedit = true">{{todo.title}}</a>
  </div>
  <div ng-show="doedit" class="boxed">
    <input type="checkbox"><input type="text" ng-model="todo.title"><br>
    <input type="date" ng-model="todo.due"><br>
    <input type="text" ng-model="todo.assigned"><br>
    <button ng-click="doedit = false">save</button>
  </div>
</div>

This should work (ignoring how the cancel button should work) but if I have a large todo list (100+ items) it will create a large amount of hidden elements which are probably never used but still bound to variables.

Is there a better way to do this? I looked at angular-xeditable which seems to dynamically add elements but it only works for simple input elements.

Or is having a large amount of hidden elements not an issue in angular?

rve
  • 5,897
  • 3
  • 40
  • 64

3 Answers3

2

ng-if removes the element from DOM entirely if it evaluates to false, including any watchers. For example:

<div ng-if="doEdit"></div>

This post explains some of the differences between ng-if and ng-show.

  • simply replacing `ng-show` with `ng-if` does not work because `ng-if` creates a child scope which means the `ng-if` never reacts to changes made by the `ng-click` – rve Mar 03 '16 at 15:50
1

Having large amounts of hidden elements is not an issue only with the js but also with the DOM itself. you should not be doing that.
What can be done instead is

1. Using ng-if - keep a state of all the element lets say isEdited after the user clicks on the todo. Set the variable / state isEdited = !isEdited. This would set it to true if it is not already. Then inside your DOM write HTML using ng-if. Something like this

<div class="to-do-item"></div><br>
<div ng-if="isEdited">
<!--UI for the edited part-->
</div>

Since ng-if does not render the html till the condition is true. There wont be too much load on the DOM.

2. If the template for editing the to do item is same for all the todo items. You should prefer using ng-include with ng-if. This way the template would be downloaded the first time you try to edit the element. Then you can cache it so not network lag. Also there is no extra hidden html. Whatever needs to be on the page is on the page and is not hidden.

Parv Sharma
  • 12,581
  • 4
  • 48
  • 80
  • simply replacing `ng-show` with `ng-if` does not work because `ng-if` creates a child scope which means the `ng-if` never reacts to changes made by the `ng-click` – rve Mar 03 '16 at 15:50
0

Wrapping all of that editing section into one container with an ng-if would reduce the number of internal watches down to one for the whole section when it wasn't active

charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • simply replacing `ng-show` with `ng-if` does not work because `ng-if` creates a child scope which means the `ng-if` never reacts to changes made by the `ng-click` – rve Mar 03 '16 at 15:50
  • @rve...depends on behavior expected. It will at that scope level. Not sure what expected behavior is – charlietfl Mar 03 '16 at 16:01