Zcythe
Zcythe

Reputation: 13

How to pass an angular scope object to a newly created DOM

I have an angular object(model) created in controller.

$scope.deletedres = [];

I am trying to append a new DOM to the html body along with the angular object(modal) as shown below.

$('body').append('<span>'+restaurant.name+' have been removed.</span><a class=&quot;btn-flat yellow-text&quot; href="#"; ng-click="addRestaurant($scope.deletedres[$scope.deletedres.length-1])">Undo<a>');

When I view it with google chrome dev tools, it shows that $scope.deletedres as [object Object] and addRestaurant() function receive nothing.

Can anyone enlighten me on this issue?

Is there any other ways to reference/pass an angular modal to a newly created DOM?

Upvotes: 0

Views: 121

Answers (3)

Harish
Harish

Reputation: 101

The way you are adding the DOM is wrong. Add the html inside the scope of controller. Use ng-show to show or hide the dom. JQuery is not necessary. Example

<span ng-show="restaurant.delete">{{restaurant.name}} have been removed.</span>
<a class=&quot;btn-flat yellow-text&quot; href="#"; ng-click="restaurant.delete=false">Undo<a>

This is just an example you can improve on

When you use jQuery to add fragments of HTML there is no way for angular to parse it. Thats the reason your angular code inside the html is working.

Upvotes: 1

kavare
kavare

Reputation: 1806

Dmitry Bezzubenkov is right. If you want to manipulate DOM with Angular, you should do that with your custom directive, rather than do that in your controller directly. And to do so, you may refer to $compile service. Here's the official document for that.

However, in your case, I believe what you actually want to do is remove the item from a list while enable the item to be recovered from deletion. In this sense, you may try this approach with Angular:

  1. In your controller, create a array for original restaurant list and another for deleted restaurant list. (Let's say, $scope.res and $scope.deletedres)
  2. Register a delete function and bind that to delete button with ng-click. In this function, you will remove the item from $scope.res and then push the item to $scope.deletedres
  3. Register another undo function. Basically do the same thing as delete function but in reverse. That is, move a item from $scope.deletedres to $scope.res. Bind this item to UNDO text in your message box.
  4. use ng-repeat to show your $scope.res list in the main container, and $scope.deletedres in the message box container.
  5. Thanks to the 2-way data binding from Angular, now you can delete or undo the action by clicking to different item.

It would be something like this:

angular
    .module('modelTest', [])
    .controller('MainCtrl', function($scope) {
      $scope.res = [
          {id: 1, name: 'Restaurant1'},
          {id: 2, name: 'Restaurant2'},
          {id: 3, name: 'Restaurant3'}
        ];

      $scope.deletedres = [];           

      $scope.delete = function(id) {
         var item, obj, i, j;
         for(i = 0, j = $scope.res.length; i < j; i++) {
             obj = $scope.res[i];

             if(obj.id === id) {
                $scope.deletedres.push(obj);
                $scope.res.splice(i, 1);
             }
          }
       };

       $scope.undo = function(id) {
           var item, obj, i, j;
           for(i = 0, j = $scope.deletedres.length; i < j; i++) {
              obj = $scope.deletedres[i];

              if(obj.id === id) {
                $scope.res.push(obj);
                $scope.deletedres.splice(i, 1);
              }
           }
        }
    });

Here's the sample code.

Upvotes: 0

Dmitry Bezzubenkov
Dmitry Bezzubenkov

Reputation: 639

You can use $compile service.

var html = '<span>{{restaurant.name}} have been removed.</span><a class="btn-flat yellow-text" href="#"; ng-click="addRestaurant(deletedres[deletedres.length-1])">Undo</a>';
var linkFn = $compile(html);
var content = linkFn(scope);
$('body').append(content);

Still as noted by Harish it's wrong. All manipulations with DOM must be done in directives. You can create directive that will be responsible for showing some message (or custom html template) on button click.

Upvotes: 0

Related Questions