Nativescript-angular: Trying to use Placeholder to insert UILabel

Created on 10 Jun 2016  路  15Comments  路  Source: NativeScript/nativescript-angular

I am trying to add UILabel returned from a cocoapods library in place of a placeholder {N} element. As a simple test/experiment I created the label within the creatingView() event as show below,

public creatingView(e: any) {
  var nativeLabel = new UILabel(CGRectMake(10,30, 200, 60));
  nativeLabel.text = "Native"; 
  console.log(e.object); // Placeholder(8)
  console.log(e.view); // undefined
  e.view = nativeLabel;
  console.log(e.view); //<UILabel: 0x7a942e60; frame = (0 0; 200 60); text = 'Native';     userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7a9438a0>>`
}

// My template 
<Label text="above the placeholder"></Label>
<Placeholder (creatingView)="creatingView($event)"></Placeholder>
<Label text="below the placeholder"></Label>

e.view = nativeLabel; //<UILabel: 0x7a942e60; frame = (0 ...
Though the placeholder seems to have updated with the UILabel the simulator does not show it. Any thoughts?

Most helpful comment

@NickIliev Is it still true that Placeholder is not supported in Angular based applications? It seems to be working when I tried in Playground.

https://play.nativescript.org/?template=play-ng&id=QvjSyn

All 15 comments

I was working with @getmetorajesh on this tonight and also puzzled on this one, would love to know the solution.

We also tried:

e.object.view = nativeLabel;

Both Labels, above and below will render in the view of course, but we could not simply insert a native UILabel into the placeholder in between them? I feel like we were missing something obvious.

Looks like the creatingView event is fired after the view is added to the visual tree - which is too late.

Found a dirty workaround until that is fixed. Load with the component ngIf-ed and show it in the ngOnInit:

// In template:
<Placeholder *ngIf="init" (creatingView)="creatingView($event)"></Placeholder>

// In component:
public init: boolean = false;
ngOnInit() {
  this.init = true;
}

@vakrilov @VladimirAmiorkov do we know if the above ^^ is fixed? Do we still need the dirty workaround or know? Was going to try but just wanted to check if either of you knew first.

@NathanWalker I dont think it has been resolved just jet.

I tried:

import { Component, OnInit, AfterViewInit, ViewChild, ElementRef } from "@angular/core";
import { registerElement } from "nativescript-angular/element-registry";
import { Placeholder } from "ui/placeholder";
import { Label } from "ui/label"

registerElement("Placeholder", () => require("ui/placeholder").Placeholder);

@Component({
    template: `
      <Placeholder *ngIf="init" (creatingView)="creatingView($event)"></Placeholder>
    `
})

export class CameraComponent implements OnInit {

  public init: boolean = false;

  constructor() {

  }

  ngOnInit() {
    this.init = true;
  }
  ngAfterViewInit() {

  }

  creatingView(args) {
      var nativeView = new Label();
      nativeView.text = "Native";
      args.view = nativeView;
  }

}

But in the console I get the error:

CONSOLE ERROR file:///app/tns_modules/nativescript-angular/zone-js/dist/zone-nativescript.js:344:22: Error: Uncaught (in promise): Error: Element for Placeholder already registered.

I also tried it without the:
registerElement("Placeholder", () => require("ui/placeholder").Placeholder);
But then I get:

CONSOLE ERROR file:///app/tns_modules/nativescript-angular/zone-js/dist/zone-nativescript.js:344:22: Error: Uncaught (in promise): Error: Template parse errors:
Property binding ngIf not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("
[ERROR ->]<Placeholder *ngIf="init" (creatingView)="creatingView($event)"></Placeholder>"): CameraComponent@1:6

Note: Placeholder is not supported for Angular based applications.

Closing due to inactivity

@NickIliev Is it still true that Placeholder is not supported in Angular based applications? It seems to be working when I tried in Playground.

https://play.nativescript.org/?template=play-ng&id=QvjSyn

Thanks manojdcoder for his help on my post.

I think the angular way is to viewContainerRef

I don't think so, since Placeholder extends View the nativeView that will be created by default going to follow all attributes and measurements of View.

@manojdcoder Are you referring to me ? if so , it is possible and the modalDialog plugin used by NS , does use viewContainerRef.

Thank you @RoyiNamir for pointing it, I must check that. I was under assumption that using ViewContainerRef may not allow me to apply CSS styles on nativeView as it won't follow the {N} View hierarchy. I will give a try for ViewContainerRef.

@manojdcoder What did you end up with? Really looking for a definitive way to go.

@hettiger Placeholder will be my choice. Though most times I prefer writing it as a component extending from appropriate NativeScript base class and use registerElement with Angular.

Was this page helpful?
0 / 5 - 0 ratings