2014-11-30 2 views
0

Функция get_tracking() возвращает объект с свойством summary.Бесконечная петля в угловом режиме с использованием ng-bind

Я пробовал несколько разных способов сделать эту работу, но мне не повезло. Чтобы решить эту проблему, я хотел бы либо привязать свойство summary к объекту пакета, либо просто указать его в таблице.

В этом коде я сначала вытаскиваю все пакеты из базы данных и сохраняю их в $ scope.packs. Затем я хотел бы запустить функцию get_tracking() для каждого из них и применить атрибут summary к каждому пакету.

Есть ли способ запускать функцию в каждом пакете после ее возврата из базы данных? Когда я пытаюсь запустить функцию в угловом, мне не повезло, потому что объекты пакета еще не были возвращены.

HTML:

<tbody> 
<tr data-ng-repeat="pack in packs" 
data-ng-show="((authentication.user) && (authentication.user._id == pack.user._id))"> 
<td data-ng-bind="pack.tracking_number"></td> 
<td data-ng-bind="pack.description"></td> 
<td data-ng-bind="pack.company"></td> 
<td data-ng-bind=""></td> 
<td data-ng-bind="get_tracking(pack).summary"></td> 
<td ng-bind=""></td> 
</tr>  
</tbody> 

JS

$scope.get_tracking = function (packet) { 
     if (packet){ 
      $http.post('/tracking', packet).success(function(response) { 
       return response.summary; 
      }).error(function(response) { 
      }); 
     } 
    }; 

ответ

0

Плохая практика использования таких вещей, как это <td data-ng-bind="get_tracking(pack).summary"></td>. Вы отправляете запрос каждый раз, когда выполняются угловые привязки. А в обработчике вы обновляете данные, которые запускают привязки, поэтому у вас бесконечные петли в приложении.

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

+0

Спасибо за совет. Я очень новичок в угловатости и после многого чтения вижу теперь, что это ужасная практика. С тех пор я обновил свой код и решил проблему. – Matt

0

Ваша функция $ scope.get_tracking является использование $ http.post который является типом "обещание" и "возвращение response.summary;" dosn't возвращает любое значение вашей функции «get_tracking»

+0

Спасибо за то, что привлек это к моему вниманию, я попробовал немного поиграть с ним, но все равно не мог заставить его работать. – Matt

1

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

<tbody> 
    <tr data-ng-repeat="pack in packs" 
     data-ng-show="((authentication.user) && (authentication.user._id == pack.user._id))"> 
     <td data-ng-bind="pack.tracking_number"></td> 
     <td data-ng-bind="pack.description"></td> 
     <td data-ng-bind="pack.company"></td> 
     <td data-ng-bind="{{::get_tracking(pack)}}"></td> 
     <td data-ng-bind="trackingSummary[packet]"></td> 
     <td ng-bind=""></td> 
    </tr>  
</tbody> 

JS

$scope.trackingSummary = {}; 
$scope.get_tracking = function (packet) { 
    if (packet){ 
     $http.post('/tracking', packet).success(function(response) { 
      $scope.trackingSummary[packet] = response.summary; 
     }).error(function(response) { 
     }); 
    } 
}; 

ИЛИ:

<tbody> 
    <tr data-ng-repeat="pack in packs" 
     data-ng-show="((authentication.user) && (authentication.user._id == pack.user._id))"> 
     <td data-ng-bind="pack.tracking_number"></td> 
     <td data-ng-bind="pack.description"></td> 
     <td data-ng-bind="pack.company"></td> 
     <td data-ng-bind=""></td> 
     <td data-ng-bind="get_tracking(pack)"></td> 
     <td ng-bind=""></td> 
    </tr>  
</tbody> 

$scope.trackingSummary = {}; 
$scope.get_tracking = function (packet) { 
    if (packet && !$scope.trackingSummary[packet.tracking_number]){ 
     $http.post('/tracking', packet).success(function(response) { 
      $scope.trackingSummary[packet.tracking_number] = response.summary; 
     }).error(function(response) { 
     }); 
    } 
    return $scope.trackingSummary[packet.tracking_number]; 
}; 

UPDATE

Если добавить функцию для запуска, когда ваш $scope.packs загружен, вы могли убедиться, что все только вызывается один раз:


JS

$scope.trackingSummary = {}; 

$scope.get_tracking = function (packet) { 
    if (packet){ 
     $http.post('/tracking', packet).success(function(response) { 
      $scope.trackingSummary[packet.tracking_number] = response.summary; 
     }).error(function(response) { 
     }); 
    } 
}; 

//after packs loaded 
var onLoadedFunc = function() { 
    for (var i = 0; i < $scope.packs.length; i++) { 
     $scope.get_tracking($scope.packs[i]); 
    } 
}; 

//when you know that the packs collection is loaded: 
onLoadedFunc(); 

Это должно предотвратить бесконечное переваривать петлю, как вызов свойство объекта не приведет к дайджеста каждый раз, как функция будет.и если бы не изменится, как только вы загрузили порядок packs, можно также передать индекс в и установите резюме на сам объект:

var onLoadedFunc = function() { 
    for (var i = 0; i < $scope.packs.length; i++) { 
     $scope.get_tracking($scope.packs[i], i); 
    } 
}; 

$scope.get_tracking = function (packet, index) { 
    if (packet){ 
     $http.post('/tracking', packet).success(function(response) { 
      $scope.packs[i].summary = response.summary; 
     }).error(function(response) { 
     }); 
    } 
}; 

Позволяющ для HTML, как так:

[...] 
<td data-ng-bind="pack.summary"></td> 
[...] 

Вы также может удалить функцию из области действия, поскольку она будет вызываться только кодом в контроллере, если только вам не потребуется обновлять или изменять сводку без перезагрузки области/вида

+0

У меня не было легкого доступа к некоторому коду передо мной, поэтому у него могло бы быть несколько проблем, которые нужно было бы решить, чтобы предотвратить множественные вызовы на сервере, но примите его скорее как концепцию. – tophallen

+0

Спасибо за помощь, которая работает лучше, и я могу получить значения, которые я искал, но теперь я получаю следующую ошибку: Ошибка: [$ rootScope: infdig] 10 $ digest() достигнуты итерации. Aborting! – Matt

+0

Можете ли вы добавить обновленный код, вызывающий цикл '$ digest'? - Я подозреваю, что это связано с тем, что цикл дайджеста проверяет изменение значения один раз в секунду, поэтому, когда он вызывает эту функцию, он вызывает ее каждую секунду, и вы получаете несколько запросов к серверу в очереди, лично я бы рекомендуется вызывать функцию для каждого элемента в '$ scope.packs', когда контроллер загружается, а не встраивает его в ng-repeat, чтобы гарантировать, что он вызывается только один раз на загрузку страницы. – tophallen