Привязка данных не работает для атрибутов тега A-frame

Я делаю приложение WebVR с aframe и angular-cli. Я загружаю некоторые статические данные 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": ""
        }
    ]
}

Я загружу hotspots в моем HTML-коде с этим кодом:

<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 содержит местоположение изображения.

Проблема с кодом выше в том, что атрибуты position, rotation а также scale не будет связывать В отображаемом выводе переменные пусты, но 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>

Не могли бы вы найти ошибку в моем коде?

заранее спасибо

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-тегать уникальный идентификатор. 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>

Причина того, что угловая привязка данных не работает, приведена здесь.

Используя одностороннюю привязку данных Angular, вы на самом деле устанавливаете свойства ваших фреймов. Однако в действительности таких свойств не существует. Это на самом деле атрибуты этих элементов. Следовательно, вы можете манипулировать областью через 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>

Вы можете заставить это работать в шаблоне (без каких-либо a-entitysetup в классе контроллера) с помощью синтаксиса привязки атрибута [attr.*], например

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

(И идентификатор элемента не требуется.)

ССЫЛКА: /questions/20113980/kak-ukazat-polozhenie-obekta-v-ramke-ispolzuya-uglovyie-parametryi/20113985#20113985

Не беспокойтесь о том, что вы видите в DOM Inspector. То, что вы связываете, все еще влияет на саму сцену, верно? Если так, то я думаю, что это ответит:

https://aframe.io/docs/0.5.0/introduction/faq.html

Из соображений производительности A-Frame не обновляет DOM данными компонента. Используйте компонент отладки, чтобы включить сериализацию компонента в DOM.

По умолчанию из соображений производительности A-Frame не обновляет DOM данными компонента. Если мы откроем инспектор DOM браузера, мы увидим, что у многих объектов будет видно только имя компонента:

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

Данные компонента хранятся внутри. Обновление DOM требует времени ЦП для преобразования данных компонентов, которые хранятся внутри, в строки. Однако, когда мы хотим увидеть обновление DOM для целей отладки, мы можем прикрепить отладочный компонент к сцене. Компоненты проверят, включен ли компонент отладки, прежде чем пытаться сериализовать в DOM. Тогда мы сможем просматривать данные компонентов в DOM:

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

Убедитесь, что этот компонент не активен в производстве.

Другие вопросы по тегам