0

I am trying to create a directive that iterates through an array of vendor objects, each vendor has an comments array property. I wanted to add a text area in the directive that would populate the comments array in link method of the directive. I was not able to get the value from text area, what am I doing wrong

my controller >>

.controller("VendorController",function($scope){

  $scope.vendors = [
        {
          id : 1,
          name : "foo",
          comments:[]
        },

        {
          id : 2,
          name : "boo",
          comments:[]
        }

    ]

})

my directive>>

.directive('vendorInterests',function(){
     return{
        restrict:'E',
        replace: true,
        scope: {
            vendors: "=",
            comment :"="
        },
        ,
    template:"<div>"+
                "<div ng-repeat='vendor in vendors'><div>{{vendor.name}}"+
                "</div>"+
                "<div ng-repeat='comment in vendor.comments'>{{comment}}</div>"+
                " <textarea  rows='5'  ng-model='comment'></textarea>"+
                " <button  ng-click='addComment(vendor)'>Add Comment</button>"+
             "</div>",
        link:function(scope, elem, attrs){

             scope.addComment=function(vendor){
             //scope.comment is coming empty, how do i pass the comment into
             //this method and update the view
               console.log(scope.comment);
               //console.log(cntrl.$viewValue.comment);
             vendor.comments.push(scope.comment);
           }


            }
         } 
});

my html>>

<body ng-app="dealApp">
    <div ng-controller="VendorController">
      <vendor-interests vendors="vendors"></vendor-interests>
    </div>
  </body>

Please find the plunker here

MeanMan
  • 1,040
  • 10
  • 25
  • 1
    This is happening because the `ng-repeat` has created an inner scope which is subject to inheritance issues (**always** use a dot in `ng-model` - http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs). In this case, you will need an object outside the `ng-repeat` able to hold the value, which will likely be easier if you use a controller rather than link. – Claies Jun 12 '16 at 09:13

1 Answers1

0

You can achieve the above using following two approaches

Approach 1

You can have a property at your vendor level for new comments and then on button click you can push it to the comments array like below

.directive('vendorInterests',function(){
     return{
        restrict:'E',
        replace: true,
        scope: {
            vendors: "=",
            comment :"="
        },
        template:"<div>"+
                    "<div ng-repeat='vendor in vendors'><div>{{vendor.name}}"+
                    "</div>"+
                    "<div ng-repeat='comment in vendor.comments'>{{comment}}</div>"+
                    " <textarea  rows='5'  ng-model='vendor.newComment' ></textarea>"+
                    " <button  ng-click='addComment(vendor)'>Add Comment</button>"+
                 "</div>",
        link:function(scope, elem, attrs){

             scope.addComment=function(vendor){
                 vendor.comments.push(vendor.newComment);
           }


            }
         } 
});

Approach 2

You can have something like below where you can set your comment on ng-blur and then can add it on the button click

.directive('vendorInterests',function(){
     return{
        restrict:'E',
        replace: true,
        scope: {
            vendors: "=",
            comment :"="
        },
        template:"<div>"+
                    "<div ng-repeat='vendor in vendors'><div>{{vendor.name}}"+
                    "</div>"+
                    "<div ng-repeat='comment in vendor.comments'>{{comment}}</div>"+
                    " <textarea  rows='5'  ng-model='comment' ng-blur='setNewComment(comment)'></textarea>"+
                    " <button  ng-click='addComment(vendor)'>Add Comment</button>"+
                 "</div>",
        link:function(scope, elem, attrs){
          var comment;
              scope.setNewComment=function(c){
                comment=c;
              }
             scope.addComment=function(vendor){
               debugger;
              // console.log(scope.comment);
               //console.log(cntrl.$viewValue.comment);
             vendor.comments.push(comment);
           }


            }
         } 
});
Rishi Tiwari
  • 1,041
  • 1
  • 10
  • 20