【问题标题】:Databinding does not work for A-frame tag attributes数据绑定不适用于 A-frame 标签属性
【发布时间】:2017-03-23 13:15:27
【问题描述】:

我正在使用 制作一个WebVR 应用程序。我从资产中加载一些静态 JSON 数据并将其绑定到 A-frame 元素。这是我的 JSON 数据示例。

{
    "id": 4,
    "image": "",
    "location": "Font",
    "nextScenes": [
        3,
        5
    ],
    "hotspots": [
        {
            "id": "obj1",
            "location": "2325 1305 -2400",
            "rotation": "-5 -50 -5",
            "scale": "150 150 150",
            "headerTitle": "",
            "body": ""
        },
        {
            "id": "obj2",
            "location": "3145 890 -2175",
            "rotation": "-5 -50 -5",
            "scale": "150 150 150",
            "headerTitle": "",
            "body": ""
        }
    ]
}

我将使用此代码在我的 HTML 代码中加载 hotspots

<a-scene inspector="url: https://aframe.io/releases/0.3.0/aframe-inspector.min.js">
    <a-assets>
        <img id="sky" [src]="currentImageSource" alt="" />
    </a-assets>

    <a-sky src="#sky"></a-sky>

    <!-- problems with code below -->
    <a-entity *ngFor="let spot of currentData.hotspots; let i = index" [id]="spot.id" 
              [position]="spot.location" [rotation]="spot.rotation" [scale]="spot.scale" 
              visible="true" mixin="null" color="pink" 
              text="zOffset:0;value:S;height:100;width:100;align:center"></a-entity>
</a-scene>

请注意,currentData 等于上面的 JSON 代码,currentImageSource 包含图像的位置。

上面代码的问题是属性positionrotationscale不会绑定。在呈现的输出中,变量为空,但 ng-reflect-... 属性不为空。

此外,如果我使用 ctrl + alt + I 检查代码,则该对象将a-entity 标记为默认值。

更新一:属性id的数据绑定有效。

更新二:在这里您可以在我的浏览器中看到输出:

<app-vrtour _nghost-pub-1="">
  <a-scene class="fullscreen" inspector="" canvas="" keyboard-shortcuts="" screenshot="" vr-mode-ui="" auto-enter-vr="" _ngcontent-pub-1="">
    <a-assets _ngcontent-pub-1="">
      <ewalswebvr-static-assets _ngcontent-pub-1=""><img id="#details" crossorigin="anonymous" scr="/assets/images/details.jpg"></ewalswebvr-static-assets>
      <img id="sky" alt="" src="assets/360images/P5.tif" ng-reflect-src="assets/360images/P5.tif" _ngcontent-pub-1="">
    </a-assets>

    <!--template bindings={"ng-reflect-ng-for-of": "[object Object],[object Object]"}-->
    <!-- The two tags below are the lines that wouldn't bind -->
    <a-entity id="obj1" mixin="null" text="" ng-reflect-id="obj1" ng-reflect-position="2323.81 1305.90 -2400" ng-reflect-rotation="-4.58 -48.7 -5.16" ng-reflect-scale="150 150 150" ng-reflect-visible="true" position="" rotation="" scale="" visible=""
      _ngcontent-pub-1="" ng-reflect-color="#ff0000"></a-entity>
    <a-entity id="obj2" mixin="null" text="" ng-reflect-id="obj2" ng-reflect-position="3145.63 889.46 -2176.50" ng-reflect-rotation="-4.58 -48.7 -5.16" ng-reflect-scale="150 150 150" position="" rotation="" scale="" visible="" _ngcontent-pub-1=""
      ng-reflect-color="#00ff00"></a-entity>

    <a-sky src="#sky" material="" position="" rotation="" scale="" visible="" geometry="" _ngcontent-pub-1=""></a-sky>

    <canvas width="1920" height="930" class="a-canvas a-grab-cursor" style="width: 1920px; height: 930px;" data-aframe-canvas="true"></canvas>
    <div class="a-enter-vr" style="display: none;" aframe-injected=""><button class="a-enter-vr-button" aframe-injected=""></button></div>
    <div class="a-orientation-modal a-hidden" aframe-injected=""><button aframe-injected="">Exit VR</button></div>
    <a-entity aframe-injected="" position="" rotation="" scale="" visible="" camera="" wasd-controls="" look-controls="" data-aframe-inspector="default-camera"></a-entity>
    <a-entity aframe-injected="" position="" rotation="" scale="" visible="" light="" data-aframe-default-light=""></a-entity>
    <a-entity aframe-injected="" position="" rotation="" scale="" visible="" light="" data-aframe-default-light=""></a-entity>
    <a-entity position="" rotation="" scale="" visible="" camera=""></a-entity>
  </a-scene>

</app-vrtour>

你能找到我的代码中的错误吗?

提前致谢

【问题讨论】:

  • 我想知道visiblecolor 绑定是否有效?我想知道 Angular 是否也像 A-Frame 一样覆盖 .setAttribute。但似乎其他人取得了一些成功:github.com/brakmic/Angular2_VR_Starter
  • @ngokevin: 不,visiblecolor 绑定不起作用。

标签: aframe angular-cli data-binding angular-cli aframe webvr


【解决方案1】:

您可以使用 [attr.*] 属性绑定语法,例如

<a-entity *ngFor="let spot of currentData.hotspots"
              [attr.position]="spot.location" [attr.rotation]="spot.rotation"
              [attr.scale]="spot.scale"
...

(并且不需要元素 ID。)

参考号:https://stackoverflow.com/a/43733797/189518

【讨论】:

    【解决方案2】:

    角度数据绑定不起作用的原因是here

    使用 Angular 单向数据绑定,您实际上是在设置 a-frame 实体的属性。然而,在现实中,不存在这样的属性。这些实际上是这些元素的属性。因此,您可以通过 dom api 进行操作。

    但是,从安全角度来看,不建议使用 DOM api。但这也不是必需的。

    要进行属性数据绑定,可以使用类似的语法,如下所示。

    <a-entity *ngFor="let spot of currentData.hotspots; let i = index" [id]="spot.id" 
                  [attr.position]="spot.location" [attr.rotation]="spot.rotation" [attr.scale]="spot.scale" 
                  visible="true" mixin="null" color="pink" 
                  text="zOffset:0;value:S;height:100;width:100;align:center"></a-entity>
    

    【讨论】:

      【解决方案3】:

      尝试解决方法后,我找到了一个可行的解决方案。这段代码的问题是它没有使用数据绑定,我认为它的性能不如数据绑定,但 A-frame 不支持它。

      您可以在这里找到我在打字稿代码中添加的代码:

      ngAfterViewInit(): void {
      
          for (let i: number = this.currentData.hotspots.length; i--;) {
      
              let spot: any = this.currentData.hotspots[i],
                  el: any = document.getElementById(spot.id);
      
              el.setAttribute("position", spot.location);
              el.setAttribute("rotation", spot.rotation);
              el.setAttribute("scale", spot.scale);
          }
      }
      

      如果我给每个 a-entity-tag 一个唯一的 ID,则此代码有效。我的组件的 HTML 代码没有改变,但可以改用它。

      <a-entity *ngFor="let spot of currentData.hotspots; let i = index" [id]="spot.id"
                text="zOffset:0;value:S;height:100;width:100;align:center"></a-entity>
      

      【讨论】:

        【解决方案4】:

        不用担心您在 DOM Inspector 中看到的内容。您绑定的内容仍在影响场景本身,对吗?如果是这样,那么我认为这会回答:

        https://aframe.io/docs/0.5.0/introduction/faq.html#why-is-the-html-dom-not-updating-in-a-frame

        出于性能原因,A-Frame 不会使用组件数据更新 DOM。使用调试组件启用组件到 DOM 序列化。

        默认情况下,出于性能原因,A-Frame 不会使用组件数据更新 DOM。如果我们打开浏览器的 DOM 检查器,我们会看到很多实体只有组件名称可见:

        <a-entity geometry material position rotation></a-entity>
        

        组件数据在内部存储。更新 DOM 需要 CPU 时间来将内部存储的组件数据转换为字符串。但是,当我们想要查看 DOM 更新以进行调试时,我们可以将调试组件附加到场景中。组件会在尝试序列化到 DOM 之前检查是否启用了调试组件。然后我们就可以在 DOM 中查看组件数据了:

        <a-entity geometry="primitive: box" material="color: red" position="1 2 3" 
                  rotation="0 180 0"></a-entity>
        

        确保此组件在生产中未激活。

        【讨论】:

        • 好的,但是如何将我的数据绑定到属性?我需要这样做,因为每个热点都位于另一个地方。总的来说,我在几张图像上有 20 到 30 个热点。
        • 如果设置&lt;a-scene debug&gt;,浏览器输出什么?
        • 我没有看到输出的差异。
        猜你喜欢
        • 1970-01-01
        • 2018-03-24
        • 2016-05-14
        • 2016-06-06
        • 2020-01-02
        • 1970-01-01
        • 2018-12-10
        • 1970-01-01
        • 2019-06-07
        相关资源
        最近更新 更多