ng-class 在值更改时未正确更新

Posted

技术标签:

【中文标题】ng-class 在值更改时未正确更新【英文标题】:ng-class not updating properly on value change 【发布时间】:2016-02-07 10:25:31 【问题描述】:

我正在做一个需要允许用户在图像上添加/删除标签的项目。

有网格视图、单一视图和混合视图。 网格视图在网格中显示图像缩略图, 单视图一张一张显示图像 混合视图的背景是网格,前面是单个图像(放大功能)。

所有这些视图都有一个页脚,其中包含可应用于图像的标签。但是,网格有自己的页脚,而单一视图和混合视图共享它们的页脚。

这里是这些的 html 端代码:

<section id="noRefContainer" class="photosWrapper photosWrapper-cq" style="display: block"> <!--ng-controller="gridController">-->
        <div class="images-cq__wrapper" ng-show="displayStyle.style == 'grid' || displayStyle.style == 'both'">
            <div class="images-cq__item" ng-repeat="photo in displayedPhotos">
                <div ng-class="active: photo.selected">
                    <label for="photo.uuid">
                        <div class="img-cq">
                            <img ng-src="photo.thumbPath100"  ng-click="selectionEvent(value: photo.uuid, event: $event, index: $index)" />
                            <a href="#" class="zoom-cq" title="zoom" ng-click="zoomOpen(value: $index)">zoom</a>
                        </div>
                        <p>
                            photo.title
                        </p>
                    </label>
                </div>
            </div>
            <div class="images-cq__footer open">
                <p>
                    <span>Tagger les</span>
                    <strong>selectedPhotos.length</strong>
                    <span>éléments sélectionnés</span>
                </p>
                <div class="images-cq__dropdown top">
                    <a href="#">...</a>
                    <ul>
                        <li><a href="#" ng-click="selectAll()">Sélectionner toutes les images</a></li>
                        <li><a href="#" ng-click="deselectAll()">Désélectionner toutes les images</a></li>
                    </ul>
                </div>
                <div class="images-cq__tags">
                    <ul>
                        <li ng-repeat="tag in tags">
                            <a href="#" ng-class="'active': tag.status == 'active', 'selected': tag.status == 'selected'" ng-click="tagSelectionEvent(value : tag.value)">tag.name</a>
                        </li>
                    </ul>
                </div>
                <small>Attention, ceci effacera les précédents tags.</small>
            </div>
        </div>
        <div ng-class="'images-cq__lightbox': displayStyle.style == 'both', 'images-cq__wrapper': displayStyle.style == 'single', single: displayStyle.style == 'single'" ng-show="displayStyle.style == 'both' || displayStyle.style == 'single'">
            <div class="images-cq__carousel">
                <a href="" class="images-cq__carouselclose" ng-click="zoomClose()" ng-show="displayStyle.style == 'both'">
                    Close
                </a>
                <div class="images-cq__carouselcontent" id="carousel">
                </div>
                <div class="images-cq__carouselfooter">
                    <div class="images-cq__tags">
                        <ul>
                            <li ng-repeat="tag in tags">
                                <a href="#" ng-class="'active': tag.status == 'active', 'selected': tag.status == 'selected'" ng-click="zoomTagSelectionEvent(value : tag.value)">tag.name</a>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </section>

还有 app.js 端代码:

$scope.tags = [];

$scope.tags = [ name: 'CQ:OK', count: 0, status: '', value: 'CQ:OK' ,
         name: 'CQ:OK_NO_ZOOM', count: 0, status: '', value: 'CQ:OK_NO_ZOOM' ,
         name: 'CQ:KO', count: 0, status: '', value: 'CQ:KO' ,
         name: 'Chromie', count: 0, status: '', value: 'Chromie' ,
         name: 'Détourer', count: 0, status: '', value: 'Détourer' ,
         name: 'Nettoyer_redresser', count: 0, status: '', value: 'Nettoyer_redresser' ,
         name: 'Interne', count: 0, status: '', value: 'Interne' ,
         name: 'Otsc', count: 0, status: '', value: 'Otsc' ];

$scope.zoomTagSelectionEvent = function (tag) 
        var photo = $scope.carousel.settings.images[$scope.carousel.settings.currentImage];
        if ($scope.hasTag(photo, tag.value)) 
            $scope.removeTag(photo, tag.value);
        
        else 
            $scope.addTag(photo, tag.value);
        
        $scope.updateTagStatus(tag.value);
    

$scope.tagSelectionEvent = function (tag) 
        if ($scope.allHaveTag($scope.selectedPhotos, tag.value)) 
            $scope.allRemoveTag($scope.selectedPhotos, tag.value);
        
        else 
            $scope.allAddTag($scope.selectedPhotos, tag.value);
        
        $scope.updateTagStatus(tag.value);
    

$scope.updateAllTagStatus = function () 
        angular.forEach($scope.tags, function (value, key) 
            $scope.updateTagStatus(value.value);
        );
    

        $scope.updateTagStatus = function (tag) 
        var currentTag = $scope.getTag(tag);

        if ($scope.displayStyle.style == 'grid')
        
            var tagged = $scope.countTagged($scope.selectedPhotos, tag);
            if (tagged == 0) 
                currentTag.status = 'none';
            
            else if (tagged < $scope.selectedPhotos.length) 
                currentTag.status = 'selected';
            
            else 
                currentTag.status = 'active';
            
        
        else 
            if ($scope.carousel.settings.currentImage !== false)
            
                var photo = $scope.carousel.settings.images[$scope.carousel.settings.currentImage];
                var res = $scope.hasTag(photo, tag);
                if (res) 
                    currentTag.status = 'active';
                
                else 
                    currentTag.status = 'none';
                
            
        
        console.log('tag ' + tag + ' status updated');
    

每次将标签应用于图像时,都会更新标签状态,这应该会更新 ng-class 表达式结果。唯一正确更新的部分是网格页脚。仅在显示视图时在单个/混合视图更新之间共享。

至于我试图解决的问题,我尝试在每次调用标签更新后使用 $scope.apply(),尝试将其放在 updateTagStatus 函数的末尾。我还尝试更改表达式(带/不带引号的类名,将类设置为标签状态......),这些都只适用于网格页脚,但不适用于其他。我还检查了状态是否正确更新,唯一的问题是显示的更新。

请帮忙。

更新:

我很抱歉没有在这里回答,在很短的时间内有大量的项目演变列表,因此导致此问题的代码不再存在,这也完全消除了问题。我正忙于这个项目,忘了更新这个。

不过,感谢您抽出宝贵时间来帮助我。

我不确定在这种情况下我应该怎么做。

【问题讨论】:

如果你能在 Plunker 中复制它会更容易提供帮助。 我们可以得到'getTag(tag_name)'方法吗?您的 app.js 中似乎缺少它,并且可能是解决方案的关键。 【参考方案1】:

第一次看起来像var currentTag = $scope.getTag(tag); 这行是罪魁祸首。它可能不会为标签返回正确的angular object

或者您可以尝试正确使用 $apply 函数。 即用户$apply 用于每个更新语句,例如:

$scope.$apply(function ()  currentTag.status = 'selected'; );

$scope.$apply(function ()  currentTag.status = 'none'; );

【讨论】:

以上是关于ng-class 在值更改时未正确更新的主要内容,如果未能解决你的问题,请参考以下文章

合并 - 仅在值更改时更新

当类更改时,ng-class 会在 AngularJs 视图中更新 ng-repeat 中的所有项目

Nhibernate 在子集合更新时未检测到父项的更改

Angular 手表不会在值更改时触发

随着模型的变化,Angular ng-class 三元组不会更新我的模板

useState 数组在创建重复项时未正确更新