简体   繁体   English

属性指令scope.apply在ng-repeat中使用时不起作用

[英]Attribute directive scope.apply not working when used within ng-repeat

I am using an attribute directive to update the DOM, a variable called profileImage . 我正在使用属性指令来更新DOM,即名为profileImage的变量。 The attribute directive is called ppt-profile-icon and works fine as long as it is not inside ng-repeat . 该属性指令称为ppt-profile-icon ,只要它不在ng-repeat内,就可以正常工作。 I have looked through a myriad of questions on Stackoverflow and have not found a solution. 我已经浏览了关于Stackoverflow的众多问题,但没有找到解决方案。

Here is my HTML: 这是我的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>

And here is my directive: 这是我的指令:

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 my link function I have tried: 在我的link函数中,我尝试过:

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

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

Problem is, scope in your directive is the ngRepeat directive's scope, not the parent so you're only setting profileImage within the repeater. 问题是, scope在你的指令是ngRepeat指令的范围,而不是父母,所以你只设置profileImage中继器内。

I'd go with an executable binding 我会选择一个可执行的绑定

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

Then, create a function in your controller scope to set the image 然后,在控制器范围内创建一个函数以设置图像

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

and set your template like this 然后像这样设置您的模板

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

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

you should always use object in your ngModels when interacting between parend - child scopes (see https://github.com/angular/angular.js/wiki/Understanding-Scopes for more details), so just adding vm.model before primitives would be sufficient: 在parend-子作用域之间进行交互时,应始终在ngModels中使用对象(有关更多详细信息,请参见https://github.com/angular/angular.js/wiki/Understanding-Scopes ),因此只需在原始类型之前添加vm.model足够:

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

and in the link function: 并在链接功能中:

    //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 塞子: http ://plnkr.co/edit/jddW7zURZoyLA8MKkm6t?p=preview

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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