Подтвердить что ты не робот

Не удалось вызвать Object.keys в angularjs

Я использую аккордеон UI.Bootstrap, и я определил свой заголовок так:

<accordion-group ng=repeat="(cname, stations) in byClient">
    <accordion-heading>
        {{ cname }} <span class="pull-right"> {{ Object.keys(stations).length }} Stations</span>
    </accordion-heading>

При отображении Object.keys(stations).length ничего не разрешается. Если я поставлю вызов той же длины в свой контроллер, я вернусь к ожидаемому счету. Есть ли что-то, препятствующее вызову метода работать в AngularJS?

Остальная часть аккордеона, использующего stations, действует так, как ожидалось, поэтому я знаю, что она заполняется должным образом. Структура данных byClient в основном выглядит так:

{
    "Client Name" : {
        "Station Name": [
            {...},
            {...}
        ]
    }
 }
4b9b3361

Ответ 1

Да, это потому, что Object является частью window/global и angular не может оценить это выражение в области. Когда вы указываете Object.keys в своей привязке, angular пытается оценить его по сравнению с $scope, и он не находит его. Вы можете сохранить ссылку Object.keys в некоторой утилите в rootScope и использовать ее в любом месте приложения.

Что-то вроде этого: -

angular.module('yourApp',[deps...]).run(function($rootScope){
  //Just add a reference to some utility methods in rootscope.
  $rootScope.Utils = {
     keys : Object.keys
  }

  //If you want utility method to be accessed in the isolated Scope 
  //then you would add the method directly to the prototype of rootScope 
  //constructor as shown below in a rough implementation.

  //$rootScope.constructor.prototype.getKeys = Object.keys;

});

и используйте это как: -

<span class="pull-right"> {{ Utils.keys(stations).length }} Stations</span>

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

Или еще лучше создать фильтр формата, чтобы вернуть длину ключа и использовать его везде.

app.filter('keylength', function(){
  return function(input){
    if(!angular.isObject(input)){
      throw Error("Usage of non-objects with keylength filter!!")
    }
    return Object.keys(input).length;
  }
});

и выполните: -

{{ stations | keylength }}

Демо

Ответ 2

Используйте эту функцию для определения количества свойств объекта:

$scope.keyLength = function (obj) {
    return Object.keys(obj).length;
}

и используйте:

{{ keyLength(myObj) }}

Ответ 3

Я думаю, что фильтры - это самый способ AngularJS обработки структур в коде шаблона:

angular.module('app.filters').filter('objectKeysLength', [function() {
    return function(items) {
        return Object.keys(items).length;
    };
}]);

angular.module('app.filters').filter('objectKeys', [function() {
    return function(item) {
        if (!item) return null;
        var keys = Object.keys(item);
        keys.sort();
        return keys;
    };
}]);