Angular.js: svg要素の起動時の「属性の値が無効です」エラー

作成日 2012年06月13日  ·  14コメント  ·  ソース: angular/angular.js

chromeバージョン「20.0.1132.27beta」を使用しています(他のバージョンでも見られます)

このhtmlの場合(明らかに元のHTMLから簡略化されています):

<html ng-app>
  <head>
    <script src="http://code.angularjs.org/angular-1.0.0rc12.min.js"></script>
  </head>
  <body>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
      <rect x="{{0}}" y="{{0}}" width="{{100}}" height="{{100}}" fill="red"/>
    </svg>
  </body>
</html>

期待される長方形を描画しますが、JavaScriptコンソールを見ると次のように表示されます。

エラー:の値が無効です属性x = "{{0}}"のバグ。 html:7
エラー:の値が無効です属性y = "{{0}}"のバグ。 html:7
エラー:の値が無効です属性width = "{{100}}"のバグ。 html:7
エラー:の値が無効です属性height = "{{100}}"のバグ。 html:7

それは明らかに値が評価される前から来ています。 それらは無害に見えますが、気が散ります(ng-repeatが原因で、実際のコードは数千のそのようなエラーを生成します。http://dave.whipp.name/tutorial/anti-alias.htmlを参照してください)。

最も参考になるコメント

実際、最近(AngularJS 1.5)では、属性の前に「ng-attr-」を追加しているため、次のようになります。

<rect x="{{0}}" y="{{0}}" fill="red"/>

次のようになります:

<rect ng-attr-x="{{0}}" ng-attr-y="{{0}}" fill="red"/>

全てのコメント14件

このエラーを回避するためのディレクティブまたは別のAngularテクニックはありますか? Ng-cloakでは不十分です。

悲しいことに、私はこれとまったく同じ問題に遭遇しました。 おそらくChromeは、AngularJSがDOMに侵入して混乱する前に、SVGを「評価」しているのでしょうか。 (そして当然のことながら、文字列 "<[100 + v.row * 100]>"をAngularの助けを借りて数値まで評価することはできません)。

私も同じ問題を抱えています。 最後に、私は自分自身のディレクティブを書くことにしました:

angular.module('yourmodule.directives', [])
    .directive('ngX', function() {
        return function(scope, element, attrs) {
            scope.$watch(attrs.ngX, function(value) {
                element.attr('x', value);
            });
        };
    })

次に、 x代わりにng-x属性を使用します。

<circle ng-x="{{ x }}" y="0" r="5"></circle>

最後に、迷惑なエラーメッセージを取り除きました。

それは優れたソリューションです。 やってみます。 ただし、影響を受けるすべての属性に対して一連のディレクティブを作成する必要があるのではないかと思います。

ありがとう。

ngHrefやngSrcと同様に、次のことができます。

angular.forEach(['x', 'y', 'width', 'height'], function(name) {
  var ngName = 'ng' + name[0].toUpperCase() + name.slice(1);
  myModule.directive(ngName, function() {
    return function(scope, element, attrs) {
      attrs.$observe(ngName, function(value) {
        attrs.$set(name, value); 
      })
    };
  });
});

@mtillerそう思います。 すべての属性に対しても、一連のディレクティブを作成する必要がありました。 しかし、 @ rkirovが示唆したように、ループを使用してそれを行うことができます。

@ rkirovattrs 。$ observeとattrs。$ setを使用したことはありません。 scope。$ watchとelement.attrを使用するよりも優れていますか? 違いは何ですか?

そのスニペットを共有してくれてありがとう、 @ rkirovelem.setAttribute("d", "")ここで、 elempath要素です。 、ChromeはエラーコンソールにError: Problem parsing d=""を表示します。 しかし、 http://www.w3.org/TR/SVGTiny12/paths.html#DAttributeによると、 d=""は完全に有効であり、これはパスのレンダリングを無効にする方法です。 誰かがここで何が起こっているのか分かりますか? これはWebKitのバグですか?

これはWebKitのバグですか?

はい

#1925はこの問題の複製のようです。 気づかなかった、ごめんなさい。

遅延バインディングが必要な属性のプレフィックスを使用して解決する保留中のPR(https://github.com/angular/angular.js/pull/2061)があります。

残念ながら、 @ skivviesが指摘したように、 d=""に関する問題はWebKitのバグです...

素晴らしいソリューションvsirisanthana。 同じ理由で属性 'd'に線を引くと、同じエラー「期待されるmoveto pathコマンド( 'M'または 'm')angular」が発生していました。

angular.module('yourmodule.directives', [])
.directive('ngD', function () {
    return function (scope, element, attrs) {
        scope.$watch(attrs.ngD, function (value) {
            element.attr('d', value);
        });
    };
});

どうもありがとう

実際、最近(AngularJS 1.5)では、属性の前に「ng-attr-」を追加しているため、次のようになります。

<rect x="{{0}}" y="{{0}}" fill="red"/>

次のようになります:

<rect ng-attr-x="{{0}}" ng-attr-y="{{0}}" fill="red"/>

問題について

エラー:の値が無効です属性x1 = "{{viewBox.x1}}"エラー:の値が無効です属性y1 = "{{viewBox.y1}}"

x1とy1をng-attr-x1ng-attr-y1置き換えることができます

ngAttrを使用する場合、$ interpolateのallOrNothingフラグが使用されるため、補間された文字列のいずれかの式が未定義になると、属性は削除され、要素に追加されません。

dをng-attr-dに置き換えて動作しています

peterjhartに感謝します、それはうまくいきました。 リンク関数を作成してから$ onInitを使用してコンポーネントを処理すると、機能するのではないかと思っていました。

このページは役に立ちましたか?
0 / 5 - 0 評価