数据绑定不适用于A帧标记属性

时间:2017-03-23 13:15:28

标签: data-binding angular-cli aframe webvr

我正在使用创建WebVR应用程序。我从资源加载一些静态JSON数据,并将其绑定到A帧元素。以下是我的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>

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

提前致谢

4 个答案:

答案 0 :(得分:2)

给出了角度数据绑定不起作用的原因here

使用Angular一种数据绑定方法,实际上是在设置a帧实体的属性。但是,实际上,不存在此类属性。这些实际上是那些元素的属性。因此,您可以通过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>

答案 1 :(得分:1)

不要担心您在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>
     

确保此组件在生产中未处于活动状态。

答案 2 :(得分:1)

尝试解决方法后,我找到了可行的解决方案。这段代码的问题在于它没有使用数据绑定,而且数据绑定的性能较差,但A帧不支持它。

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

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 - 标记提供唯一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>

答案 3 :(得分:0)

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

)在模板中进行此操作(无需在控制器类中进行任何a-entity设置)。
<a-entity *ngFor="let spot of currentData.hotspots"
              [attr.position]="spot.location" [attr.rotation]="spot.rotation"
              [attr.scale]="spot.scale"
...

(并且不需要元素ID。)

REF:https://stackoverflow.com/a/43733797/189518