11

我正在学习 angularjs,并且正在尝试使用它ng-repeat来创建 svg 图。

我有这个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

好像和我做的不太一样……

有谁知道为什么我会收到此错误?

4

2 回答 2

12

Markus 关于使用后期绑定的评论是最好的。

IE。用'ng-attr-','ng: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>
于 2013-08-25T19:22:22.733 回答
11

问题是 Chrome 将 Angular 插值 str 视为这些属性的无效值(因为至少有一次该元素实际上存在于 DOM 中——尽管是不可见的——具有“无效”值)。我编写了一个与其他 Angular 解决方案一致的解决方案,用于浏览器处理特殊属性,而不是使用 x、y、宽度和高度,而是指定 ng-x、ng-y、ng-width 和 ng-插值后设置高度和真实属性。

这是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];
}
于 2013-05-06T06:54:07.773 回答