2015-03-05 3 views
2

Вот мой JSКак исправить эту угловую утечку памяти?

var app = angular.module('SearchAndResultsApp', ['angularUtils.directives.dirPagination']); 
app.controller('SearchAndResultsController', function($location ,$scope, $http){ 
$scope.fields = [ 
    { id: 'accountNumber', name: 'Account Number', clicked: false}, 
    { id: 'pointOfInterestName', name: 'Point Of Interest Name', clicked: true}, 
    { id: 'address1', name: 'Address 1', clicked: false}, 
    { id: 'address2', name: 'Address 2', clicked: false}, 
    { id: 'city', name: 'City', clicked: false}, 
    { id: 'isostateCode', name: 'ISO State Code', clicked: false}, 
    { id: 'postalCode', name: 'Postal Code', clicked: false}, 
    { id: 'phone', name: 'Phone', clicked: false}, 
    { id: 'fax', name: 'Fax', clicked: false}, 
    { id: 'website', name: 'Website', clicked: false}, 
    { id: 'email', name: 'Email', clicked: false}, 
    { id: 'isocountryCode', name: 'ISO Country Code', clicked: false}, 
    { id: 'latitude', name: 'Latitude', clicked: false}, 
    { id: 'longitude', name: 'Longitude', clicked: false} 
]; 

$scope.getSearchState = function() { 
    var fields = window.location.hash.substring(1).split("&"); 
    if (fields.length > 0) { 
     return decodeURIComponent(fields[0]); 
    } else { 
     return ''; 
    } 
}; 

$scope.getPageState = function() { 
    var fields = window.location.hash.substring(1).split("&"); 
    if (fields.length > 1) { 
     return parseInt(fields[1]); 
    } else { 
     return 1; 
    } 
}; 

$scope.noResults = false; 
$scope.pointsOfInterest = null; 
$scope.loadingQuery = false; 
$scope.orderDirection = 'asc'; 
$scope.glyphDirection = 'glyphicon-triangle-top'; 
$scope.orderedBy = 'pointOfInterestName'; 
$scope.previousClicked = $scope.fields[1]; 
$scope.lowerRange = 0; 
$scope.upperRange = 0; 
$scope.totalRange = 0; 
$scope.currentPage = $scope.getPageState(); 
$scope.searchString = $scope.getSearchState(); 
$scope.offset = 'col-sm-offset-4'; 
$scope.loadingOffset = 'col-sm-offset-1'; 

$scope.getResultsState = function() { 
    return ((($scope.pointsOfInterest == null)||($scope.pointsOfInterest[0] == null)) && ($scope.searchString != '')) 
}; 

$scope.downloadCSV = function(selection) { 
    if (selection == 'searched') { 
     window.location = 'pointsOfInterest/' + encodeURIComponent($scope.searchString) + '/orderedList/' + $scope.orderedBy + '/' + $scope.orderDirection + '/csv'; 
    } else if (selection == 'all') { 
     if (confirm("This may take some time.")){ 
      window.location = 'allPointsOfInterest/csv'; 
     } 
    } 
}; 

$scope.updateRanges = function() { 
    $scope.searchString = $scope.searchString = $scope.searchString.replace(/\//g,'').replace(/\\/g,''); 
    window.location.hash = encodeURIComponent($scope.searchString) + '&' + encodeURIComponent($scope.currentPage); 
    if ($scope.pointsOfInterest[0] != null) { 
     $scope.lowerRange = ($scope.currentPage - 1) * 20 + 1; 
     $scope.totalRange = $scope.pointsOfInterest.length; 
     $scope.upperRange = $scope.currentPage * 20; 
    } else { 
     $scope.lowerRange = 0; 
     $scope.totalRange = 0; 
     $scope.upperRange = 0; 
    } 
    if ($scope.upperRange > $scope.totalRange) { 
     $scope.upperRange = $scope.totalRange; 
    } 
}; 

$scope.updateGlyphs = function(field) { 
    $scope.searchString = $scope.searchString = $scope.searchString.replace(/\//g,'').replace(/\\/g,''); 
    $scope.orderedBy = field.id; 

    if ($scope.previousClicked != null) 
     $scope.previousClicked.clicked = false; 
    field.clicked = true; 

    if ($scope.previousClicked == field) { 
     if ($scope.orderDirection == 'asc') { 
      $scope.orderDirection = 'desc'; 
      $scope.glyphDirection = 'glyphicon-triangle-bottom'; 
     } else { 
      $scope.orderDirection = 'asc'; 
      $scope.glyphDirection = 'glyphicon-triangle-top'; 
     } 
    } else { 
     $scope.orderDirection = 'asc'; 
     $scope.glyphDirection = 'glyphicon-triangle-top'; 
    } 

    $scope.updatePointsOfInterest(); 

    $scope.previousClicked = field; 
}; 

$scope.updatePointsOfInterest = function() { 
    if ($scope.searchString.length != 0) { 
     $scope.loadingOffset = ''; 
     $scope.currentPage = $scope.getPageState(); 
     $scope.searchString = $scope.searchString.replace(/\//g,'').replace(/\\/g,''); 
     window.location.hash = encodeURIComponent($scope.searchString) + '&' + encodeURIComponent($scope.currentPage); 
     if ($scope.searchString == '') return; 
     $scope.loadingQuery = true; 
     $http.get('pointsOfInterest/' + encodeURIComponent($scope.searchString) + '/orderedList/' + $scope.orderedBy + '/' + $scope.orderDirection) 
      .success(function(data) { 
       $scope.pointsOfInterest = data; 
       $scope.loadingQuery = false; 
       $scope.loadingOffset = 'col-sm-offset-1'; 
       $scope.updateRanges(); 
       $scope.noResults = $scope.getResultsState(); 
       if ($scope.pointsOfInterest.length > 0) { 
        $scope.offset = ''; 
       } else { 
        $scope.offset = 'col-sm-offset-4'; 
       } 
      }) 
      .error(function(data) { 
       window.location = 'pointsOfInterest/' + encodeURIComponent($scope.searchString) + '/orderedList/' + $scope.orderedBy + '/' + $scope.orderDirection; 
      }); 
    } 
}; 

window.onhashchange = function() { 
    $scope.updatePointsOfInterest(); 
} 
$scope.updatePointsOfInterest(); 

$scope.gotoUpdatePage = function (accountNumber) { 
    window.location.href = 'pointOfInterestEditor/' + accountNumber; 
}; 

$scope.onTextClick = function ($event) { 
    $event.target.select(); 
}; 
}); 
app.directive('ngDelay', ['$timeout', function ($timeout) { 
return { 
    restrict: 'A', 
    scope: true, 
    compile: function (element, attributes) { 
     var expression = attributes['ngChange']; 
     if (!expression) 
      return; 

     var ngModel = attributes['ngModel']; 
     if (ngModel) attributes['ngModel'] = '$parent.' + ngModel; 
     attributes['ngChange'] = '$$delay.execute()'; 

     return { 
      post: function (scope, element, attributes) { 
       scope.$$delay = { 
        expression: expression, 
        delay: scope.$eval(attributes['ngDelay']), 
        execute: function() { 
         var state = scope.$$delay; 
         state.then = Date.now(); 
         $timeout(function() { 
          if (Date.now() - state.then >= state.delay) 
           scope.$parent.$eval(expression); 
         }, state.delay); 
        } 
       }; 
      } 
     } 
    } 
}; 
}]); 

я получаю утечку памяти от добавления в $ месте к контроллеру. Я хотел бы использовать $ location вместо window.location. Я не уверен, почему происходит утечка памяти. Кто-нибудь знает, почему и как это исправить?

Редактировать: Кажется, что он делает бесконечные запросы. Все еще не уверен, как это исправить.

ответ

1

Прежде всего $location сервис имеет способ hash(), который можно использовать вместо window.location.hash().

Во-вторых: вы вызываете метод на вашем контроллере, который выполняет запрос http get. Если он не работает, он меняет URL-адрес. Когда URL-адрес изменен, ваш код контроллера перезагружается, поэтому метод $scope.updatePointsOfInterest() выполняется снова и снова.

Я не уверен, почему метод $http.error() запускается. Это может быть что угодно. Проверьте свой запрос XHR на вкладке Сеть в инструментах разработчика (Chrome).

Если ваш метод $http.error() должен терпеть неудачу (это означает, что есть ошибка, и это надлежащим образом), чем исправить «зацикливание» вопрос вы можете сделать следующее:
1) либо не вызывает $scope.updatePointsOfInterest() при загрузке контроллера
2) или не изменяет URL в вашем $http.error() методы

Если вы описать то, что вы пытаетесь достичь с помощью этого метода updatePointsOfInterest() я буду в состоянии помочь вам писать правильно.

Привет, Алексей

+0

updatePointsOfInterest() выполняет получить, который обрабатывается в контроллере, где SQL-запрос выполняется, который возвращает список точек интереса. –

+0

Итак, выбирая метод $ scope.updatePointsOfInterest() непосредственно в контроллере, вы загружаете исходные данные? Если ответ «да», то вы ошибаетесь. Это должно быть сделано в маршрутизаторе с свойством разрешения. Посмотрите эту статью, например: http://odetocode.com/blogs/scott/archive/2014/05/20/using-resolve-in-angularjs-routes.aspx Если вы не хотите знакомиться с " решает "и быстро исправить, вы можете написать 2 отдельных метода: один для загрузки начального набора данных и другой для его обновления. А в первом не делают перенаправления –

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