javascript - AngularJS Directive with no Template and Sharing the updates from parent scope - Stack Overflow

I have a very simple requirement where a directive is placed inside a ng-repeat in this I wanted to pus

I have a very simple requirement where a directive is placed inside a ng-repeat in this I wanted to push down the changes to directive so it updates the UI. Meaning I want the value of Contact(not just a string reference actual object) inside my link function so I can render the UI and also change my UI when contact changes in the parent ng-repeat.

I had created a very simplified version of what I wanted to achive. It has a list of Contacts ( After researching with help of this link by Mark I know ng-repeat creates its own scope so I added an object called deep which is an object not primitive) , I am struggling to get this sorted. I also had tried to use other possible option. I dont want to paste a template in directive with ng-show/ng-class stuff because business logic is but tricky so it is easier to do it using link function. I am sure this has to do with scope and/or $observe but I dont know how to get this sorted. Also note this is a simpler version of what I wanted to achieve. I actually want value of that object to render my UI.

My Fiddle Example You will see when you click on Update Name outer repeat gets updated no the inner.

<div>
  <div ng-controller="ContactsCtrl">
    <ul>
        <li ng-repeat="contact in contacts">
            <div zippy="contact">a</div>            
        </li>
    </ul>
    <br />
    <p>Here we repeat the contacts to ensure bindings work:</p>
    <br />
    <ul>
        <li ng-repeat="contact in contacts">
            {{contact.name}} : {{contact.deep}}
        </li>
    </ul>    
  </div>
</div>



var app = angular.module( 'myApp', [] );
app.controller('ContactsCtrl', function ( $scope ) {      
    $scope.contacts = [
                        { name: 'Sharon',deep:{A:"a"}},
                        { name: 'Steve',deep:{A:"b"}},
                        { name: 'Scott',deep:{A:"c"}}
    ];

    $scope.primitiveTest=function(c){c.name=c.name+c.name; }    
    $scope.objectTest=function(c){c.deep={A:c.deep.A+c.deep.A};  }
});
app.directive('zippy',  ['$pile', function ($pile){
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {       

          /*scope.$watch(attrs.zippy, function(newValue, oldValue){
                alert('asd');
            });

          attrs.$observe('deep',function(val){ alert('asd'); });*/
        scope.$watch(attrs['zippy'],
             function (ideaNode) {      
                 var html = [];
                 html.push('<hr/><div class="clearfix" id="vote-icons" ng-click="primitiveTest('+attrs['zippy']+');" >Update Name </div> - <div class="clearfix" id="vote-icons" ng-click="objectTest('+attrs['zippy']+');">UpdateObject');              
                 html.push('</div>');
                 html.push(JSON.stringify(ideaNode));                
                 element.html(html.join(''));
                 $pile(element.contents())(scope);
             }
        );
      }
    }
  }]);

I have a very simple requirement where a directive is placed inside a ng-repeat in this I wanted to push down the changes to directive so it updates the UI. Meaning I want the value of Contact(not just a string reference actual object) inside my link function so I can render the UI and also change my UI when contact changes in the parent ng-repeat.

I had created a very simplified version of what I wanted to achive. It has a list of Contacts ( After researching with help of this link by Mark I know ng-repeat creates its own scope so I added an object called deep which is an object not primitive) , I am struggling to get this sorted. I also had tried to use other possible option. I dont want to paste a template in directive with ng-show/ng-class stuff because business logic is but tricky so it is easier to do it using link function. I am sure this has to do with scope and/or $observe but I dont know how to get this sorted. Also note this is a simpler version of what I wanted to achieve. I actually want value of that object to render my UI.

My Fiddle Example You will see when you click on Update Name outer repeat gets updated no the inner.

<div>
  <div ng-controller="ContactsCtrl">
    <ul>
        <li ng-repeat="contact in contacts">
            <div zippy="contact">a</div>            
        </li>
    </ul>
    <br />
    <p>Here we repeat the contacts to ensure bindings work:</p>
    <br />
    <ul>
        <li ng-repeat="contact in contacts">
            {{contact.name}} : {{contact.deep}}
        </li>
    </ul>    
  </div>
</div>



var app = angular.module( 'myApp', [] );
app.controller('ContactsCtrl', function ( $scope ) {      
    $scope.contacts = [
                        { name: 'Sharon',deep:{A:"a"}},
                        { name: 'Steve',deep:{A:"b"}},
                        { name: 'Scott',deep:{A:"c"}}
    ];

    $scope.primitiveTest=function(c){c.name=c.name+c.name; }    
    $scope.objectTest=function(c){c.deep={A:c.deep.A+c.deep.A};  }
});
app.directive('zippy',  ['$pile', function ($pile){
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {       

          /*scope.$watch(attrs.zippy, function(newValue, oldValue){
                alert('asd');
            });

          attrs.$observe('deep',function(val){ alert('asd'); });*/
        scope.$watch(attrs['zippy'],
             function (ideaNode) {      
                 var html = [];
                 html.push('<hr/><div class="clearfix" id="vote-icons" ng-click="primitiveTest('+attrs['zippy']+');" >Update Name </div> - <div class="clearfix" id="vote-icons" ng-click="objectTest('+attrs['zippy']+');">UpdateObject');              
                 html.push('</div>');
                 html.push(JSON.stringify(ideaNode));                
                 element.html(html.join(''));
                 $pile(element.contents())(scope);
             }
        );
      }
    }
  }]);
Share Improve this question edited May 23, 2017 at 11:50 CommunityBot 11 silver badge asked Aug 30, 2013 at 21:44 KusekKusek 5,3842 gold badges27 silver badges49 bronze badges 1
  • I am curious if were able to unit test this? – Winnemucca Commented Mar 14, 2016 at 21:09
Add a ment  | 

1 Answer 1

Reset to default 3

You can remove the $watch in the directive if you adopt the following approach.

You should use the object interpolation html.push("{{" + attrs['zippy'] + "}}"); instead of the serialized plain text string if you want the model to be interpolated and updated.

app.directive('zippy', ['$pile', function ($pile) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            var html = [];
            html.push('<hr/><div class="clearfix" id="vote-icons" ng-click="primitiveTest(' + attrs['zippy'] + ');" >Update Name </div> - <div class="clearfix" id="vote-icons" ng-click="objectTest(' + attrs['zippy'] + ');">UpdateObject');
            html.push('</div>');
            html.push("{{" + attrs['zippy'] + "}}");
            element.html(html.join(''));
            $pile(element.contents())(scope);
        }
    }
}]);

Working Demo

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745419340a4626896.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信