1

I'm trying to add a jQuery listener on a button that is being printed with AngularJS, the listener fails to work since the element is not yet available on DOM:

var app = angular.module('myapp', []);

socket.on('datasources/update:done', function () {
  socket.emit('datasources/list');
});

socket.emit('datasources/list');
app.factory('socket', function ($rootScope) {
  return {
    on: function (eventName, callback) {
      socket.on(eventName, function () {
        var args = arguments;
        $rootScope.$apply(function () {
          callback.apply(socket, args);
        });
      });
    },
    emit: function (eventName, data, callback) {
      socket.emit(eventName, data, function () {
        var args = arguments;
        $rootScope.$apply(function () {
          if (callback) {
            callback.apply(socket, args);
          }
        });
      })
    }
  };
});

function dslist($scope, socket) {
  socket.on('datasources/list:done', function (datasources) {
    $scope.datasources = datasources.datasources;
  });
}

angular.element(document).ready(function() {
  $('.delete-data-source').on('click', function(event) {
    console.log('a');
  })
});

HTML tag (jade):

html(lang='en', ng-app="myapp" xmlns:ng="http://angularjs.org")

Relevant HTML body (jade):

.box-content(ng-controller="dslist")
                table.table.table-bordered.table-striped
                  thead
                    tr(role="row")
                      th: strong Name
                      th: strong Type
                      th: strong Tables
                      th: strong Records
                      th: strong Status
                      th: strong Action
                  tbody

                    tr(ng-repeat="ds in datasources", ng-cloak)
                      td {{ds.name}}
                      td {{ds.type}}
                      td {{ds.numTables || 0 }}
                      td {{ds.numRecords || 0 }}
                      td {{ds.status || 'UNKNOWN' }}
                      td: button.delete-data-source(data-id="{{ds.name}}") Delete
Or Weinberger
  • 7,332
  • 23
  • 71
  • 116
  • firstly in angular app should bind events from within angular. You are thinking `jQuery first` which is bad approach. Even if it was a good approach,you aren't using event delegation within the jQuery you wrote. – charlietfl Nov 26 '13 at 14:26
  • 1
    should read this: [how-do-i-think-in-angularjs-if-i-have-a-jquery-background](http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background) – charlietfl Nov 26 '13 at 14:27
  • @charlietfl This looks awesome, reading it now! thanks. – Or Weinberger Nov 26 '13 at 14:30
  • 2
    when starting with angular.... don't even include jQuery in page. Makes it easier to get into looking for angular approach first. Will be amazed how little jQuery you will actually use – charlietfl Nov 26 '13 at 14:33

1 Answers1

2

Try this:

$(document).on('click', '.delete-data-source', function(event) {
    console.log('a');
});

But i think you have wrong approach. You should have something like this:

<div ng-repeat="datasource in datasources">
     <input type="button" ng-click="remove(datasource)" value="remove"/>
</div>

In Controller:

$scope.remove = function(datasource){
    $scope.datasources.splice($scope.datasources.indexOf(datasource), 1);
}
karaxuna
  • 26,752
  • 13
  • 82
  • 117
  • This works, but for some reason only on the second click.. Can you explain about the difference between your code and mine? – Or Weinberger Nov 26 '13 at 14:29
  • The difference is that my code is listening for documents click event and then finds out if clicked element has `.delete-data-source` class asigned and your code tries to find element with class `.delete-data-source` but it is not yet added to dom, so can't find it – karaxuna Nov 26 '13 at 14:33