prem89 prem89 - 3 months ago 10
AngularJS Question

Append a dom element on ng-click to a specific class

I have a set of elements that when clicked needs to append a dom element to its nearest class

data-here
instead of element that was clicked. How do i get it done? Is there a method similar to
.closest()
to get it working..Here is the sample plunker code -> http://plnkr.co/edit/6VQwGcpX7zsjDSGc3mHp?p=preview

<div ng-repeat="n in [5, 4, 3, 2, 1] " style="border:solid 1px;" ng-click="clickme($event)">
Click me!
<div class="user">User
<div class="chata">
Chat Data
</div>
</div>
<div class="wresponse">Response Data </div>
<div class="data-here" style="border:solid 1px;">
Append Here
</div>
<br/>
</div>

Answer

Don't manipulate the DOM in a controller! It violates the entire point of AngularJS as an app framework.

Here's how I'd do it.

  1. Use an ng-repeat structure for your appended list of elements. It'll start out empty.
  2. Use a directive or a controller function to handle the click event. Add to the view model on click, which will automatically update the view (and your ng-repeat structure).

Here's an example.

<div ng-repeat="thing in ctrl.things track by $index" 
  ng-click="ctrl.clickme(thing, $index+1)">
    <button>Click me!</button>

    <div class="user">User
      <div class="chata">
        Chat Data
      </div>
    </div>

    <div class="wresponse">Response Data </div>

    <div ng-repeat="word in thing.words track by $index">
      {{thing.words[$index]}}
    </div>
</div>

app.controller('MainCtrl', function() {
  var ctrl = this;
  ctrl.name = 'World';
  ctrl.things = [{
    words: ["thing one's word"]
  }, {
    words: ["thing two's word"]
  }, {
    words: ["thing three's word"]
  }];

  ctrl.clickme = function(thing, i) {
    thing.words.push('another thing ' + i + ' word');
  };
});

Plunker demo

No DOM manipulation!

Note that I used track by $index in this example to deal with duplicate items in the repeat structure.

Also, look into using controllerAs syntax. It simplifies quite a few things to do with scope.


If you absolutely must manipulate the DOM, do it in a custom directive. This keeps your controller clean and doing only what controllers should do, which is to update the view model.

Comments