2013-05-01 6 views
10

Я изучаю angularjs, и я пытаюсь использовать ng-repeat для создания графика svg.Использование svg с angularjs ng-repeat

У меня есть этот HTML:

<svg> 
    <g id="g_{{$index}}" ng-repeat="i in range" ng-cloak> 
     <rect x="{{i/5}}" y="{{i/5}}" width="{{i/5}}" height="{{i/5}}"></rect> 
    </g> 
</svg> 

'Диапазон' всего лишь простой массив, который определен в контроллере так:

$scope.range = [100, 200, 300]; 

HTML, работает; прямоугольники отображаются на моей странице.

Однако Chrome продолжает бросать следующее сообщение об ошибке:

Error: Invalid value for <rect> attribute height="{{i/5}}" js/angular.js:1584 
    JQLiteClone js/angular.js:1584 
    JQLite.(anonymous function) js/angular.js:2163 
    publicLinkFn js/angular.js:3862 
    ngRepeatWatch js/angular.js:13641 
    Scope.$digest js/angular.js:7889 
    Scope.$apply js/angular.js:8097 
    js/angular.js:961 
    invoke js/angular.js:2857 
    resumeBootstrapInternal js/angular.js:959 
    bootstrap js/angular.js:973 
    angularInit js/angular.js:934 
    js/angular.js:14756 
    fire js/jquery-2.0.0.js:2863 
    self.fireWith js/jquery-2.0.0.js:2975 
    jQuery.extend.ready js/jquery-2.0.0.js:398 
    completed js/jquery-2.0.0.js:93 

Кажется, что это не совсем нравится то, что я делаю ...

Кто-нибудь есть идея, почему я получаю это ошибка?

ответ

9

Проблема заключается в том, что Chrome считает, что угловая интерполяция str является недопустимым значением для этих атрибутов (поскольку по крайней мере однажды элемент фактически существует в DOM - хотя и невидимо - с «недопустимыми» значениями). Я написал решение, которое согласуется с другими решениями с угловыми углами, как с обработкой браузером специальных атрибутов, где вместо использования x, y, width и height вы указываете ng-x, ng-y, ng-width и ng- высота и реальные атрибуты задаются после интерполяции значений.

Вот решение on JSFiddle. Я собираюсь представить патч для Angular, чтобы узнать, можем ли мы получить это в ядре.

комментарий HTML

<div ng-app="SampleApp" ng-controller="MainCtrl"> 
    <svg> 
     <g id="g_{{$index}}" ng-repeat="i in range" ng-cloak> 
      <rect ng-x="{{i/5}}" ng-y="{{i/5}}" ng-width="{{i/5}}" ng-height="{{i/5}}"></rect> 
     </g> 
    </svg> 
</div> 

JS

angular.module('SampleApp', [], function() {}) 
    .directive('ngX', function() { 
     return function(scope, elem, attrs) { 
      attrs.$observe('ngX', function(x) { 
       elem.attr('x', x); 
      }); 
     }; 
    }) 
    .directive('ngY', function() { 
     return function(scope, elem, attrs) { 
      attrs.$observe('ngY', function(y) { 
       elem.attr('y', y); 
      }); 
     }; 
    }) 
    .directive('ngWidth', function() { 
     return function(scope, elem, attrs) { 
      attrs.$observe('ngWidth', function(width) { 
       elem.attr('width', width); 
      }); 
     }; 
    }) 
    .directive('ngHeight', function() { 
     return function(scope, elem, attrs) { 
      attrs.$observe('ngHeight', function(height) { 
       elem.attr('height', height); 
      }); 
     }; 
    }); 

function MainCtrl($scope) { 
    $scope.range = [100, 200, 300]; 
} 
+9

углового 1.1.4 (или, возможно, раньше) имеет новую общую директиву связывать конец HTTPS : //github.com/lrlopez/angular.js/commit/638e6fdbd60f606dfbe21303f9c94e6d57f0764a – hooblei

+0

@markus, оба из ваших решений работали блестяще, я принимаю подход attr-ng, как он есть в базе кода –

+0

Это потрясающе, @markus! –

10

Маркуса использовать позднее связывание лучше.

Т.е. префикс вашего атрибута либо с «нг-attr-», «нг: атр:» или «ng_attr_», как это:

<rect ng:attr:x="{{i/5}}" ng:attr:y="{{i/5}}" ng:attr:width="{{i/5}}" nng:attr:height="{{i/5}}"></rect> 
+1

Perfect, I имел те же проблемы при использовании ng-repeat, что он показывал ошибки при использовании x и y svg attrs, и это решило его. – ericsicons

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

  • Нет связанных вопросов^_^