2014-09-12 2 views
0

Я был привлечен, чтобы исправить сайт, который был в огне пару месяцев назад. У меня есть большинство вещей под контролем, и я собираюсь установить различные элементы списка пожеланий. Один из них связан с некоторым угловым кодом, который я просто не могу сделать, чтобы делать то, что хочу. На некоторых страницах есть видеоролики, за которыми следует короткая викторина. Мне нужно обновить оценки пользователя после каждого события. До сих пор, это оказалось достаточно легко общий балл, который выглядел так:Как обновить угловой тег

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

И получил обновленный с этим:

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

До сих пор, так хорошо. Однако другие элементы на странице до сих пор оказались недоступными для обновления. Вот что на странице:.

Я добавил «ID =» refreshvideo»себя, так что я мог бы попытаться изменить тег Наконец, вот угловой модуль для простого круга (я ушел из фактический код рисования, так как это не совсем уместно):

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; 

Ни одна из этих вещей не работала. Я проверил холст элемент в источнике в браузере, и я смог увидеть значение и значение данных теги меняются независимо от того, что я их установил, но изображение не изменилось. Я устанавливаю неправильную вещь? (Возможно, все, что угодно $ смотреть смотрит) Должен ли я заставить какую-то перекраску холста ?

+0

Подход - это все неправильно. Angular обновит live html на основе значений из переменных модели области в контроллерах и директивах. – charlietfl

+0

«подход - это все неправильно» определяет этот проект. Я не создал его. Тем не менее, мне все еще нужно что-то сделать из того, что я описал выше. Это поможет подсказка, где начать быстро исправлять это. – Argle

ответ

2

@charlietfl означает, что ваше решение фактически не использует AngularJS - вы полностью обходите его. Угловой обеспечивает двустороннюю привязку данных между данными Javascript и HTML DOM. Все, что вы делаете, это указать, где взять данные, и это сделает это автоматически, сохраняя его актуальным с того момента, когда данные будут изменены.

В Угловом, вы никогда не вызываете getElementById, и некоторые никогда не устанавливают innerHTML, потому что тогда вы блокируете Angular от выполнения своей задачи - во многих случаях вы фактически ее нарушаете. Каждый из этих экземпляров вводит новую ошибку, а «исправляет» другую.

Возвращайтесь в свой пример шаблона линии:

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

Когда он видит это, Угловое создаст то, что она называет «наблюдателем» на profile.currentScore. Если его значение сейчас равно «1», оно отображает это как <a ...>1</a>.

Каждый цикл дайджеста, этот наблюдатель скажет ему, чтобы он посмотрел на profile.currentScore, чтобы узнать, не изменилось ли оно. Эта строка коды является довольно типичной в JS:

profile.currentScore = 42; 

Угловой будет «видеть» это произойдет через этот наблюдатель, и будет автоматически обновлять обработанный шаблон. Вы ничего не делаете - и если вы когда-нибудь почувствуете, что вам это нужно, это почти всегда означает что-то еще ошибочно.

Если вы столкнулись с этим, попробуйте «стандартное быстрое исправление». Мы видим это много с людьми, которые не архивировали приложение должным образом, и они делают обновления модели данных вне цикла Angular's digest, где они не могут «видеть» их. Попробуйте оборачивать код обновления в $ применяется() вызов:

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

Если у вас есть много обновлений, чтобы сделать, и вы не хотите, чтобы гнездиться на вызов, вы можете также обмануть, как это:

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

$scope.$apply(); 

Вы сразу же узнаете, если вам нужно это сделать. Если это сработает, вам нужно это сделать. :) Если вы получите сообщение об ошибке в своей консоли, в котором говорится, что вы уже находитесь в цикле дайджеста, вам НЕ нужно это делать (это что-то еще).

+0

BTW, я ответил на вопрос «не обновлять данные», потому что это, по-видимому, ваша основная проблема. Но если ваш CIRCLE не обновляется, это может быть другое. Имейте в виду, что функции «link» с угловым указателем выполняются только один раз. Сделано правильно, что $ watch можно перезапустить ... но multiplyLength никогда не изменится с 2 на 1, например, даже если $ scope.value станет 5 ... Возможно, вы также будете более счастливы с привязкой '=' scope а не «@» ... –

+0

* sigh * Я предполагаю, что проблема в том, что то, что должно произойти, - это то, что я пробовал в первую очередь. В коде есть значение $ scope.profile, и при его отладке я вижу, что в нем есть существующие и правильные данные. Но я меняю $ scope.profile.currentScore и ничего не происходит на странице. Мне становится ясно, что «профиль», который я изменяю, не тот, который используется внутри {{profile.? }} на странице. В настоящее время я не знаю, как соединить эти точки. – Argle

+0

О, и спасибо за ваш ответ. В основном я получаю концепции в угловатых выражениях, и ваши комментарии были более полезными, но я никогда не кодировал ничего с собой. Несколько месяцев назад программист sorta стал изгоем в проекте и заменил огромные биты интерфейса угловыми версиями ... все без какого-либо контроля со стороны руководства или других программистов.Я просто пробираюсь слишком много сейчас. – Argle

0

Я упомянул, что я думал, что, возможно, я изменял неправильный профиль переменный, и поэтому он не был освежающим. Так что я посмотрел немного в коде, который поставляет номера:

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 вытягивается из профиля, но я не совсем понимаю, как, что получает где это. Я полагаю, что мне нужно будет понять это, потому что есть другое место, где эти обновления должны произойти, что не хватает Профиль информации. В любом случае я добавил последние 4 строки вместо этого:

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

... и все работало согласно плану. Думаю, я займусь другой частью позже, когда узнаю, как данные попадают на контроллер.

0

Вы не можете сделать это таким образом. Это не угловой способ работы с данными. Прочитайте документацию до https://docs.angularjs.org/tutorial/step_04 Если вам нужно изменить документ DOM с помощью документа .. возможно, это неправильно с вашим кодом.

BTW. Прекратить использование глобальных переменных, таких как:

document.getElementById('updateafterscore') 
Смежные вопросы