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
4
  • 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. Commented Nov 26, 2013 at 14:26
  • 1
    should read this: how-do-i-think-in-angularjs-if-i-have-a-jquery-background Commented Nov 26, 2013 at 14:27
  • @charlietfl This looks awesome, reading it now! thanks. Commented Nov 26, 2013 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 Commented Nov 26, 2013 at 14:33

1 Answer 1

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);
}
Sign up to request clarification or add additional context in comments.

2 Comments

This works, but for some reason only on the second click.. Can you explain about the difference between your code and mine?
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.