Bind custom javascript event to angular

2019-06-07 05:55发布

问题:

I'm working on a mobile application where I have list with some items. This list can be pulled down to inititate a refresh of the list (I'm using iScroll4). I'm now trying to hook this event up to my angular controller so I can make an api call and update the model.

The javascript is basically as follows:

[..] //javascript code to detect the pulldown event

function pullDownAction(){
     //I want to update the scope here
}

Based on what I have read, I need to make an angular directive and call the event from there, but I still haven't figured out where the above piece of code should go.

I have also tried broadcasting the event from within the pullDownAction function and listening to it in the controller, like so:

function pullDownAction(){
    var $rootScope = angular.injector(['ng']).get('$rootScope');
    $rootScope.$apply(function(){
          $rootScope.$broadcast('updateInbox');
    });
});

and then in the controller:

$scope.$on('updateInbox', function(){
     $http.get(apiUrl)
         .success(function (data) {
              $scope.model = data;
        });           
});

But I'm sure I'm missing something important which makes the code not work. I'm quite new to angular, so I haven't really gotten the hang of how directives work yet.

回答1:

In the link function of your directive, setup the iScroll4 plugin. Define pullDownAction() inside your link function also. Then, due to the closure, you will have access to the scope.

app.directive('iscroll4Wrapper', function() {
    return {
       link: function(element, scope, attrs) {
          var pullDownAction = function() {
            // update scope here
          }
          $(??).iScroll4({   // I have no idea how to initialize this
            onSomeEvent: function(...) {
               pullDownAction();
               scope.$apply();  // or put this in pullDownAction()
            }
          });
       }
    }
}

What you tried with the injector didn't work because you created new injector.



回答2:

I made it work by putting all the javascript code for the event in the link function:

app.directive('pullToRefresh', function () {
return {
    restrict: 'AC',
    link:
    function (scope, element, attr) {
            //Code to detect when element is pulled goes here

            function pullDownAction(){
                 scope.$eval(attr.pulldown);
            }

I then just put an attribute in the container called pulldown, and they now have access to the same scope. My element looks like this:

<div class="pull-to-refresh" pulldown="update()">
   //Element to be "pull-to-refreshable" here
</div>

update() is of course a function in the controller where you can do whatever you want!