ng-bind-html在点击锚标记或ng-click之前不显示

ng-bind-html not displaying until click of anchor tag or ng-click

本文关键字:ng-click 显示 ng-bind-html      更新时间:2024-02-10

我有一个小方法,可以计算用户评分平均值,并将其作为视觉表示输出给用户。

我遇到的问题是,ratingrateDisplay的方法结果都不会显示,直到我点击锚标记或执行ng点击。我不明白为什么,因为这个方法和任何锚标记/ng点击都是完全独立的。我试过登录以确保它在我想要的时候执行,而且确实如此。以前,当我使用车把时,我在显示三括号转义的视觉表示时没有遇到任何问题。但自从搬到Angular后,我在这方面遇到了问题。我已将ngSanitize作为依赖项包含在内。

quickblox.js

    listRatings: function(names, businesses) {
            var data = { _parent_id: names };
            QB.data.list("Comments", data, function(err, result) {
                if (err) {
                    // console.log("There was an error: " + err);
                } else {
                    console.log('ok we start nao');    // confirm we execute when we need to
                    var comps = {};
                    for (var i=0, len=result.items.length; i<len; i++) {
                        if (!comps[result.items[i]._parent_id]) {
                            comps[result.items[i]._parent_id] = [];
                        }
                        comps[result.items[i]._parent_id].push(result.items[i]);
                    }
                    for (var name in names) {
                        if (!(names[name] in comps)) {
                            for (var business in businesses) {
                                if (businesses[business].id == names[name]) {
                                    businesses[business].rating = '';
                                    businesses[business].rateDisplay = '  No comments yet, be the first!'.substr(1);
                                }
                            }
                        } else {
                            var sum = 0;
                            for (var j=0, len=comps[names[name]].length; j<len; j++) {
                                sum += parseInt(comps[names[name]][j].rating);
                            }
                            var avg = sum/comps[names[name]].length;
                            var avgFinal = 0;
                            if (avg.toFixed(1) % 1 === 0) {
                                avgFinal = avg + '/5';
                            } else if (avg.toFixed(1) % 1 !== 0) {
                                avgFinal = avg.toFixed(1) + '/5';
                            }
                            var needsHalf = (avg.toFixed(1) % 1);
                            var fullRating = '';
                            for (var k=0; k<5; k++) {
                                if (k < Math.floor(avg)) {
                                    fullRating += '<span class="icon-circle"></span>';
                                }
                                else if (needsHalf) {
                                    fullRating += '<span class="icon-half"></span>';
                                    needsHalf = false;
                                }
                                else {
                                    fullRating += '<span class="icon-none"></span>';
                                }
                            }
                            for (var business in businesses) {
                                if (businesses[business].id === names[name]) {
                                    businesses[business].rating = avgFinal;
                                    businesses[business].rateDisplay = fullRating;
                                }
                            }
                        }
                    }
                }
            });
        }

结果.js

    $scope.businesses = [];
    $scope.results = [];       // didn't show how I populate this, not necessary 
    var names = [];
    // grab data to be applied to $scope.businesses
    getData.getBusinesses()
        .then(function(data) {
            var tempBusinesses = data,
                tempConditionData;
            for (var business in tempBusinesses) {
                tempConditionData = tempBusinesses[business].conditionData;
                for (var condition in tempConditionData) {
                    if (tempConditionData[condition].id === $scope.results.id && tempConditionData[condition].published === true) {
                        names.push(tempBusinesses[business].id);
                        $scope.businesses.push(tempBusinesses[business]);
                    }   
                }
            }
        })
        .then(function() {
            quickblox.listRatings(names, $scope.businesses);
        })
        .then(function() {
            $scope.dataLoaded = true;
        }, 
        function(err) {
            $log.log('something went wrong: ' + err);
        });

最后,

results.html

<tr ng-repeat="business in businesses | orderBy:sortBy:reverse">
    <td class="4u provider-info">
        {{business.name}} 
        <br> 
        <span ng-bind-html="business.rateDisplay"></span> <small>{{business.rating}}</small> 
    </td>
</tr>

我还运行了几次JSHint,没有出现任何错误。有什么想法吗?

编辑

根据要求,这是我的getBusinesses() 代码

appData.factory('getData', ['$q', '$http', function($q, $http) {
    'use strict';
    var baseURL = 'http://someapiurl.com/';
    return { 
        // ...
        getBusinesses:function() {
            return $http.get(baseURL + 'businesses')
                .then(function(res) {
                    if (typeof res.data === 'object') {
                        return res.data;
                    } else {
                        return $q.reject(res.data);
                    }
                },
                function(err) {
                    return $q.reject(err.data);
                });
        }
    };
});

在不完全知道幕后发生了什么的情况下,我将猜测您有一个异步操作发生在"Angular world"之外。换言之,Angular不会意识到对作用域公开变量的更改已经发生,并且不会触发摘要循环,直到您单击了一个带有ng-click的按钮,例如,该按钮会触发摘要。

可能发生这种情况的地方在这里:

QB.data.list("Comments", data, function(err, result) {
});

这是一个异步操作,对吗?是否在完成时调用处理程序函数?

如果在那里为作用域变量分配任何内容,则Angular将看不到它,除非调用$scope.$apply。假设您将当前处理程序函数分解为yourCurrentHandler:

function yourCurrentHandler(err, result){
   // whatever you do right now
   // ...
}
QB.data.list("Comments", data, function(err, result) {
   $scope.$apply(function(){ 
      yourCurrentHandler(err, result); 
   }); 
});

带有示例的plunker