2014-10-10 2 views
0

я написал довольно простой тест приложение следующим образом:обновление данных между контроллером, обслуживание и директивы

angular.module('tddApp', []) 

.controller('MainCtrl', function ($scope, $rootScope, BetslipService) { 
    $scope.displayEvents = [ 
     { 
      id: 1, 
      name: 'Belarus v Ukraine', 
      homeTeam: 'Belarus', 
      awayTeam: 'Ukraine', 
      markets: {home: '2/1', draw: '3/2', away: '5/3'}, 
      display: true 
     } 
    ]; 
    $scope.betslipArray = BetslipService.betslipArray; 
    $scope.oddsBtnCallback = BetslipService.addToBetslip; 
    $scope.clearBetslip = BetslipService.clearBetslip; 
}) 

.directive('oddsButton', function() { 
    return { 
     template: '<div class="odds-btn">{{market}}</div>', 
     replace: true, 
     scope: { 
      market: '@', 
      marketName: '@', 
      eventName: '@', 
      callback: '&' 
     }, 
     link: function (scope, element) { 

      element.on('click', function() { 
       scope.callback({ 
        name: scope.eventName, 
        marketName: scope.marketName, 
        odds:scope.market 
       }); 
      }); 
     } 
    }; 
}) 

.factory ('BetslipService', function ($rootScope) { 
    var rtnObject = {}; 

    rtnObject.betslipArray = []; 

    rtnObject.addToBetslip = function (name, marketName, odds) { 
     rtnObject.betslipArray.push({ 
      eventName: name, 
      marketName: marketName, 
      odds: odds 
     }); 
    }; 

    rtnObject.clearBetslip = function() { 
     rtnObject.betslipArray = []; 
    }; 

    return rtnObject; 
}); 

Я назначен массив в переменной контроллера. Я также назначил функции для изменения массива. Чтобы добавить объект в массив, обратный вызов вызывается директивой с областью выделения. Происходит какое-то странное поведение, которое я не совсем понимаю:

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

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

NB

Я установил массив не очищая путем изменения функции в службе:

while (rtnObject.betslipArray.length > 0) { 
    rtnObject.betslipArray.pop(); 
} 
// instead of 
rtnObject.betslipArray = []; 

Это имеет смысл, поскольку служебная переменная была указана на новый объект, в то время как старая ссылка сохранялась в контроллере.

Я получил html для обновления путем переноса обратного вызова в директиве в области. $ Apply(). Эта часть, которую я действительно не понимаю. Каким образом область действия. $ Apply(), вызываемая в директиве, влияет на область контроллера, когда директива имеет область выделения? обновлено скрипку: http://jsfiddle.net/b6ww0rx8/7/

Любая мысль-х высоко оценили

jsfiddle: http://jsfiddle.net/b6ww0rx8/5/

C

+0

Я на самом деле добавить 'console.log' заявления в вашей службе и часы заявление в контроллере для массива, и я что ваш контроллер не обновляется. Массив в службе - это не контроллер. –

+0

Я сделал аналогичный тест. Я не уверен, почему часы $ не собирают это, но если я назначу область управления переменной переменной в службе и зарегистрирую ее как http://jsfiddle.net/b6ww0rx8/6/, она выглядит как контроллер обновляется – Cathal

+0

Вы добавляете ресурс и занимаете много времени в цикле, чтобы усечь ваш массив?Кроме того, вы используете 'pop()' в своем массиве, чтобы полностью удалить элементы, что также связано с затратами? 'array.length = 0', одна строка отсутствует, нет времени сосать. Что произойдет, если у вас есть тысячи элементов в этом массиве? Ваш цикл while может занять слишком много времени и повесить ваше приложение. –

ответ

1

Я получил это работает здесь: http://jsfiddle.net/b6ww0rx8/8/

Добавлено $q, $scope.$emit и $timeout пункты, чтобы помочь с коммуникациями между вашей директивой/службой и контроллером.

Я также хотел бы сказать, что я не буду назначать служебные функции контроллеру. $scope, Вы должны определить функции в контроллере, вызывающие служебные функции.

Вместо этого:

$scope.clearBetslip = BetslipService.clearBetslip; 

ли это:

$scope.clearBetslip = function(){ 
    BetslipService.clearBetslip().then(function(){ 
     $scope.betslipArray = BetslipService.getBetslipArray(); 
    }); 
}; 
+0

Я не уверен, согласен ли я с вами в этом. В сущности, угловой способ - отвлечь как можно больше логики от контроллеров. Что случилось с назначением метода службы переменной $ scope? – Cathal

+1

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

+1

Услуги должны извлекать, сохранять/отправлять, обрабатывать данные и располагать логикой для этого, таким образом, да, вы правы, служба абстрагирует логику от контроллера. Но контроллер должен знать, как использовать эту услугу, ни в коем случае мой пример выше не добавляет дополнительную логику контроллеру. Контроллер вызывает только сервисный метод для maniuplate данных и ждет завершения службы, если его удастся затем обновить массив контроллера, чтобы мы могли соответствующим образом обновить отображение. В обещании есть очень минимальная логика, и в этом случае она подходит. –

Смежные вопросы