如何刷新角度标签

时间:2014-09-12 15:35:37

标签: javascript jquery html angularjs canvas

我被带到修复一个几个月前着火的网站。我已经控制了大部分事情,而且我还要修复各种愿望清单项目。其中一个涉及一些角度代码,我似乎无法做我想做的事情。在某些页面上有视频,然后是简短的测验。我需要在每次活动后更新用户的分数。到目前为止,事实证明这对于总得分来说已经足够容易了:

 <a id="updateafterscore" href="~/user/leaderboard/" class="fill-div">
                                {{ profile.currentScore }}
                            </a>

这更新了:

document.getElementById('updateafterscore').innerHTML = data.Data.CurrentScore;

到目前为止,这么好。然而,到目前为止,页面上的其他元素无法更新。这是页面上的内容:

我添加了&#34; id =&#34; refreshvideo&#34;我自己也可以尝试改变标签。最后,这里是简单圆的角度模块(我已经省略了实际的绘图代码,因为它并不真正相关):

angular.module('thrive.shared').directive('simpleCircle', function() {

return{
    replace: true,
    template: '<canvas width="60" height="60" style="margin: -10px 0 0 -15px;"></canvas>',
    restrict: 'E',
    scope: {
        value: '@',
        color: '@',
        bgColor: '@',
        forecolor: '@',
        radius: '@'
    },
    link: function (scope, elem, attrs) {

        var multiplyLength = 1;
        var canvasElem = elem[0];
        var inMotion = false;

        if (scope.value <= 2) {
            multiplyLength = 5;
        }

        scope.$watch('value', function() {
            drawCircle(canvasElem, scope.color, scope.value * multiplyLength, scope.value, scope.name);
        });


        function drawCircle(canvas, color, calculatedPoints, displayPoints, name) {

那么,问题是:如何更新显示的数字?我尝试了各种各样的事情:

document.getElementById('refreshvideo').setAttribute('value', data.Data.VideoWatchedCount);
document.getElementById('refreshvideo').setAttribute('data-value', data.Data.VideoWatchedCount);
$scope.profile.videosWatched = data.Data.VideoWatchedCount;

这些都不起作用。我在浏览器的源代码中检查了 canvas 元素,我可以看到数据值标签更改为我设置的内容,但图像保持不变。我说错了吗? (或许 $ watch 正在观看)我是否必须强制重新绘制 canvas 元素?

3 个答案:

答案 0 :(得分:2)

@charlietfl意味着你的解决方案实际上并没有使用AngularJS - 你完全绕过了它。 Angular提供Javascript数据和HTML DOM之间的双向数据绑定。您所做的就是告诉它在哪里绘制数据,它会自动为您完成,随着数据的变化使其保持最新状态。

在Angular中,你永远不会调用getElementById,并且肯定从不设置innerHTML,因为那时你阻止Angular做它的事情 - 在很多情况下你真的会破坏它。这些实例中的每一个都在“修补”另一个实例时引入了新的错误。

返回示例模板行:

<a ..attributes...>{{ profile.currentScore }}</a>

当它看到这一点时,Angular将在profile.currentScore上创建它所谓的“观察者”。如果它现在的值为'1',则会将其呈现为<a ...>1</a>

每个摘要周期,观察者都会告诉它查看profile.currentScore以查看它是否发生了变化。这行代码在JS中非常典型:

profile.currentScore = 42;

Angular将通过该观察者“看到”这种情况,并将自动更新渲染的模板。你什么都不做 - 如果你觉得你需要,它几乎总是意味着 else 是错误的。

如果您遇到这种情况,请尝试“标准快速修复”。我们对那些没有正确构建应用程序的人有很多看法,并且他们正在Angular的摘要周期之外进行数据模型更新,而不能“看到”它们。尝试在$ apply()调用中包装更新代码:

$scope.$apply(function() {
    profile.currentScore = 42;
});

如果你有很多更新要做并且你不想嵌套这个电话,你也可以作弊,这样:

// Lots of stuff...
profile.currentScore = 42;
// Lots more stuff...

$scope.$apply();

如果你需要这样做,你马上就会知道。如果它有效,你需要这样做。 :)如果你在控制台中收到一条错误消息,说你已经处于摘要周期,你不需要这样做(这是其他的)。

答案 1 :(得分:0)

我提到过,我想也许我正在修改错误的 profile 变量,因此它并不令人耳目一新。所以我回顾了提供数字的代码:

angular.module('episodes').controller('episodeCtrl', ['$scope', '$rootScope', '$window', 'episode', 'relatedCourses', 'Video', 'episodeItems', 'profile', 'Profile',
function ($scope, $rootScope, $window, episode, relatedCourses, Video, episodeItems, profile, Profile) {
// stuff skipped....
                        onComplete: function () {
                            Video.complete({ videoId: item.item.id }).$promise.then(function () {
                                item.progress = "Completed";
                                $scope.loadNextItem();
                                $scope.profile = Profile.get();   // <<-- gotten from somewhere

                                $.ajaxSetup({ cache: false });
                                $.get('/user/getCurrentUserPointsModel', function (data) {
                                    if (data == "")
                                        return;
                                    $scope.profile.currentScore = data.Data.CurrentScore;
                                    $scope.profile.videosWatched = data.Data.VideoWatchedCount;
                                    $scope.profile.testTakenAndCorrectAnswerCount = data.Data.TestTakenAndCorrectAnswerCount;
                                    Profile.save();    // <-- added

$ scope.profile 中的值是从个人资料中提取的,但我还没有完全了解它的位置。我想我需要弄明白这一点,因为这些更新必须发生在另一个地方,缺少 Profile 信息。无论如何,我添加了最后4行代替:

document.getElementById('updateafterscore').innerHTML = data.Data.CurrentScore;

......所有人都按计划工作。当我弄清楚数据是如何进入控制器的时候,我想我后来处理了另一部分。

答案 2 :(得分:0)

你不能这样做。它不是处理数据的Angular方式。 在https://docs.angularjs.org/tutorial/step_04之前阅读文档 如果您需要使用文档修改DOM ..可能是您的代码错误。

顺便说一句。停止使用全局变量,如:

document.getElementById('updateafterscore')