2013-05-01 21 views
10

Angularjs öğreniyorum ve svg grafiği oluşturmak için ng-repeat kullanmayı deniyorum.Angularjs ng-yineleme ile svg kullanın

Bu html vardır:

<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> 

'aralığı' bu gibi kontrol ünitesine de tanımlandığı basit bir dizidir: HTML çalışmaktadır

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

; rects sayfamda işlenir.

Ancak, Chrome şu hatayı atıp duruyor:

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 

Oldukça ne yaptığımı gibi değil mi görünüyor ...

kimse bunu alıyorum neden bir fikir var mı hata?

cevap

9

Sorun, Chrome'un, bu öznitelikler için geçersiz bir değer olarak (bu öğede görünmez olsa da - gerçekte "geçersiz" değerlerle en azından bir kez DOM'da var olduğu için) geçersiz bir değer olduğunu görür. X, y, width ve height kullanmak yerine, ng-x, ng-y, ng-width ve ng-belirttiğiniz özel niteliklerin tarayıcı kullanımını ele alan diğer Açısal çözümlerle uyumlu bir çözüm yazdım. Değerler enterpolasyondan sonra yükseklik ve gerçek öznitelikler ayarlanır.

İşte çözüm on JSFiddle. Bunu çekirdekte bulabileceğimizi görmek için Angular'a bir yama göndereceğim.

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

açısal 1.1.4 (ya da belki daha eski) bağlamak için yeni bir genel yönetmeliğe sahiptir geç https : //github.com/lrlopez/angular.js/commit/638e6fdbd60f606dfbe21303f9c94e6d57f0764a – hooblei

+0

@markus, her iki çözümünüz de mükemmel bir şekilde çalıştı, –

+0

kod tabanındaki attr-ng-yaklaşımını benimsiyorum Bu harika, @markus! –

10

Markus' comment geç bağlama kullanmak en iyisidir.

Ie. Bu gibi ya da 'ng_attr_' ya 'ng-attr-', ': özn ng': ile öznitelik önüne

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

Mükemmel, ng-repeat kullanırken aynı sorunları vardı x kullanırken hatalar gösteriyordu ve y svg attrs ve bunu çözdü. – ericsicons