简体   繁体   中英

Remove Item from parent scope array

I am trying to remove an item from the json array defined in my controller after a user clicks delete button. The button resides inside a html template for the directive.

Here is my controller

listVMS.controller('vmInfoController', ['$scope', function($scope) {
  var json = [{
             image: 'img/fedora.png',
             status: 'running',
             name: 'Fedora',
             ip: '192.168.3.354',
             cores: '5',
             ram: '2GB',
             storage: '20GB'
             }];
  $scope.vms = json;

  $scope.removeVM = function() {
    alert("Hello, World");
  };
}]);

My directive

listVMS.directive('vmInfo', function() { 
  return { 
    restrict: 'E', 
    scope: { 
      info: '=', 
      rmv: '&',
    }, 
    templateUrl: 'views/vmInfo.html',
    link: function(scope, element, attrs) {
      if(scope.info.status == 'running') {
        scope.buttonText = 'Pause';
        scope.act = 'pause';
      }
      else {
        scope.buttonText = 'Play';
        scope.act = 'play-circle';        
      }

      scope.sos = function() {
        if (scope.info.status == 'paused') {
          scope.info.status = "running";
          scope.buttonText = "Pause";
          scope.act = "pause";
        }
        else {
          scope.info.status = "paused";
          scope.buttonText = "Play";
          scope.act = "play-circle";
        }
      }
      scope.deleteVM = function(){
        scope.rmv();
      }
    },
  };
});

I am using ng-repeat to repeat here

<div class="row" ng-repeat="vm in vms">
     <vm-info info="vm"></vm-info>
</div>

inside the template for the directive I have a button that should fire ng-click()

<button type="button" class="btn btn-danger btn-lg center-block" ng-click="removeVM">Delete <span class='glyphicon glyphicon-remove'></span></button>

I want to click the delete button and remove the specific item from the scope. So when the scope is reloaded then that div for that item won't be there either, but the onclick is not firing from inside the template. Please help I am new to angularjs and directives are tricky to me.

In your directive you are trying to bind the rmv but you never pass rmv to the vm-info directive.

<div class="row" ng-repeat="vm in vms">
     <vm-info info="vm" rmv="removeVM"></vm-info>
</div>

The ng-click will be evaluated when clicked. I'm guessing it should pass the VM to the controller. Instead of having the directive call this method through an in-between method you can pass the rmv function directly to the ng-click and take out the deleteVM method in your directive.

<button type="button"
        class="btn btn-danger btn-lg center-block"
        ng-click="rmv(info)">
    Delete <span class='glyphicon glyphicon-remove'></span>
</button>

Finally, the controller receives the vm and removes it.

$scope.removeVM = function(vm){
    // remove vm from $scope.vms
}

您正在处理模块控制器中的单击,而应该通过指令控制器执行此操作时,另一种方法是将ng-click添加到隔离的指令范围中,从而将函数传递给范围变量。

While you can solve it this way, I would recommend using $emit for this purpose.

Instead of passing a function of parent scope down to child scope, you can write an event handler $on on your parent scope and then emit the event from your child scope using $emit .

In the event handler you can delete the record that you want.

I was having a problem removing the element from the list in my template, even though I was removing the list item from array using parent scope.

I even emmited the even and tried to splice the item from array in parent controller. Even though the item was getting removed from the array(console.log) but the template was not modified.

$rootScope.$emit('eventname', {
  param1: val1,
  param2: val2
});

$rootScope.$on('eventname', function(event, args) {
  if (args.param1 && args.param2) {
    //logic for removing here
  }
});

But it didn't work as stated above. So, I gave unique id's to each div using the id of the element getting repeated. And I edited the display property to make it 'none'. This is useful in cases we are loading results from the API into the array and then into the template.

Hope it helps someone. Also, if this is performance wise very un-optimized, please let me know.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM