2016-10-12 2 views
1

Ich verwende eine attribute-Direktive, um das DOM, eine Variable namens profileImage zu aktualisieren. Die Attributrichtlinie heißt ppt-profile-icon und funktioniert gut, solange sie nicht innerhalb von ng-repeat liegt. Ich habe eine Vielzahl von Fragen zu Stackoverflow durchgesehen und keine Lösung gefunden.Attribut richtlinie scope.apply funktioniert nicht, wenn innerhalb ng-repeat verwendet

Hier ist mein HTML:

<div class="img-preview" ng-style="{'background-image': 'url(' + profileImage + ')'}"></div> 


<ul class="dropdown-menu pre-defined-icons" uib-dropdown-menu role="menu" aria-labelledby="single-button"> 
    <li ng-repeat="predefinedImage in vm.predefinedImages"> 
     <a> 
      <img ppt-profile-icon src="{{predefinedImage}}" width="100%" /> 
     </a> 
    </li> 

    <!--This, outside of the ng-repeat will work--> 
    <li> 
     <a> 
      <img ppt-profile-icon src="content/img/people/noProfileIcon.svg" width="100%" /> 
     </a> 
    </li> 
</ul> 

Und hier ist meine Richtlinie:

angular 
    .module('app.core') 
    .directive('pptProfileIcon', function ($timeout) { 
     //link function for DOM Minipulation 
     function linkFunction(scope, elem, attrs) { 
      elem.bind('click', function() { 
       scope.profileImage = attrs.src; 
       scope.$apply(); 
      }); 

     }//end 

     //Directive Declaration 
     return { 
      restrict: "A", 
      controller: ['$scope', function ($scope) { 
       //sets enviornment 
      }], 
      link: linkFunction 
     }//end 

    });//end 

In meiner link Funktion, die ich versucht habe:

attrs.$observe('src', function (val) { 
    $timeout(function() { 
     scope.profileImage = val; 
     scope.$apply(); 
    }); 
}); 

$timeout(function() { 
    scope.profileImage = attrs.src; 
    scope.$apply(); 
}); 
+0

mit '$ scope $ apply' ist im allgemeinen ein Codegeruch. Es gibt Möglichkeiten, dies zu beheben, so dass "$ apply" wieder funktionieren würde, aber dies sollte ein Hinweis darauf sein, dass es eine gute Investition der Zeit ist, einen saubereren Weg zu finden, um Ihr Update durchzuführen, das nicht $ apply beinhaltet. – Claies

+0

@Claies Ich stimme zu, ich mag nicht, wo ich mit diesem bin, es ist ein kommerzielles Projekt, also versuche ich, nur mit dieser so weit zu schneiden, meine ganze App, sonst ist Komponenten, AngularJs 1.5 Stil, alles in einer Richtung Bindung. Keinen Spielraum. Diese Direktive ist hier, weil ich einen Input-Typ = Datei habe und ich kann das DOM nicht mit meiner Komponentenbasis in einem file.Reader-Event manipulieren. Diese Direktive wird nur in einer Komponente verwendet und es ist Code-Geruch –

Antwort

1

Problem ist, scope in Ihrem Richtlinie ist der Anwendungsbereich der Richtlinie ngRepeat, nicht die Eltern, also bist du o Nur Einstellung profileImage im Repeater.

ich mit einem ausführbaren gehen würde Bindung

.directive('pptProfileIcon', function() { 
    return { 
     restrict: 'A', 
     scope: { 
      pptProfileIcon: '&' 
     }, 
     link: function(scope, elem) { 
      elem.on('click', function() { 
       scope.pptProfileIcon({ 
        profileImage: elem.prop('src') 
       }); 
       scope.$apply(); 
      }); 
     } 
    } 
}) 

Dann eine Funktion in der Steuerungsbereich erstellen um das Bild zu setzen

$scope.setProfileImage = function(image) { 
    $scope.profileImage = image; 
}; 

und stellen Sie Ihre Vorlage wie folgt

<img ppt-profile-icon="setProfileImage(profileImage)" ng-src="{{predefinedImage}}" /> 

Plunker demo ~ http://plnkr.co/edit/GqFXqZW5AmLCyWHblBDN?p=preview

1

sollen Sie immer Objekt in Ihrem ngModels verwenden, wenn zwischen parend der Interaktion - geordneten Bereichen (siehe https://github.com/angular/angular.js/wiki/Understanding-Scopes für weitere Details), so dass nur vm.model Zugabe vor Primitiven ausreichen würden:

<div class="img-preview" 
    ng-style="{'background-image': 'url(' + vm.model.profileImage + ')'}"></div> 

und in der Verbindung Funktion:

//link function for DOM Minipulation 
    function linkFunction(scope, elem, attrs) { 

     elem.bind('click', function() { 
      scope.vm.model.profileImage = attrs.src; 
      scope.$apply(); 
     }); 

    }//end 

Plunker. http://plnkr.co/edit/jddW7zURZoyLA8MKkm6t?p=preview

Verwandte Themen