【问题标题】:Use svg with angularjs ng-repeat将 svg 与 angularjs ng-repeat 一起使用
【发布时间】:2013-04-25 11:42:05
【问题描述】:

我正在学习 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

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

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

【问题讨论】:

    标签: angularjs-ng-repeat


    【解决方案1】:

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

    即。为您的属性添加前缀“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>
    

    【讨论】:

    • 完美,我在使用 ng-repeat 时遇到了同样的问题,使用 x 和 y svg attrs 时显示错误,这解决了。
    【解决方案2】:

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

    【讨论】:

    • angular 1.1.4(或者更早版本)有一个新的通用指令来绑定后期github.com/lrlopez/angular.js/commit/…
    • @markus,您的两个解决方案都非常出色,我采用了 attr-ng- 方法,就像它在代码库中一样
    • 由于这是公认的答案,我认为值得将其更改为使用官方后期绑定属性ng-attr-xng-attr-y... 并将其余部分保留为 DIY
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-07
    • 2019-05-13
    • 1970-01-01
    相关资源
    最近更新 更多