Is there a way to access an elements parent in tritium? - css-selectors

for example, let's say there was this html:
<div>
<div id="divchild"></div>
</div>
Would there be a way to access the parent div from the child elements namespace such as:
$$('#divchild'){
# Access parent div here
$$('< div'){
# somethere here
}
}
Is there a way to take the non working example and make it work? thank you.

not with the css selectors.You'll need to use xpath selectors:
$(".//div[div[#id='divchild']]") {
# something here
}
or
$(".//div[#id='divchild']/parent::div") {
# something here
}
would select the parent div.

Related

reference component variable from ng-content

I have the following piece of markup:
<group-header [isOpen]="true">
<div *ngIf="isOpen">{{'PRICE' | resource}}</div>
</group-header>
group-header's template looks like this:
<div (click)="toggleGroups($event);">
<ng-content></ng-content>
</div>
isOpen is defined in my group-header component like this:
#Input()
set isOpen(value: boolean) {
this._isOpen = value;
}
get isOpen() {
return this._isOpen;
}
Apparently I cannot reference isOpen the way I want to (or at all for that matter) as my 'PRICE' resource never displays.
Is there a way to have my ng-content rendered content display conditionally based on a field on my component?
Hope this all makes sense... if not please ask
EDIT: Added setter as per #PierreDuc's comment :-)
You can use a template variable to reference the GroupHeader component:
<group-header [isOpen]="true" #gh>
<div *ngIf="gh.isOpen">{{'PRICE' | resource}}</div>
</group-header>

What is way to access parent component property in child component in AngularJS 1.5?

I have parent and child component, and have some element to hide and show using <ng-if> by isTrue property value. but currently, facing trouble to do the same.
Exact Scenario:
I have a property called 'isTrue' in parent components controller and passing it to child using isTrue: '<'. Now, in child component, I need to hide something using isTrue property value which I have no issue to do so.
Now. again the cycle repeats the same but this time again I want to hard-reset isTrue in the parent component using isTrueCheck() and again send back to the child component. now, isTrue should set to true and sent it to child component.
Summery:
similarly whenever I call isTrueCheck(), I just want to set 'isTrue' to true and send it to child component.
I have tried to set it into $onInit().
Parent controller:
this.isTrue;
this.isTrueCHeck = function(){
isTrue = true;
};
Child controller:
isTrue: '<'
if (isTrue){
isTrue= false;
}
Child HTML/template
<div ng-click="isTrueCheck"></div>// Calling to reset `isTrue` property
<div ng-if="$ctrl.isTrue">ele1</div>
<div ng-if="!$ctrl.isTrue">ele2</div>
Now, I want to call parent controller and hard reset to true and do the same procedure.
I am not sure I understood your problem.
am I right if I say:
You have a parent component and some children
You have a variable 'isTrue' set in parent and want to propagate it in children. When 'isTrue' changes in the parent, you want to trigger it in children.
Well, if so, in children you need to implement the $onChange method in your children:
isTrue: '<'
the one above is your variable passed from parent.
//
// React to changes of *one-way bindings* (< and #) of a component
// see http://blog.thoughtram.io/angularjs/2016/03/29/exploring-angular-1.5-lifecycle-hooks.html
// see https://toddmotto.com/angular-1-5-lifecycle-hooks#onchanges
ctrl.$onChanges = function (changesObj) {
// if isTrue changes, do something
if (changesObj.isTrue && changesObj.isTrue.currentValue) {
// do something...
// ....
}
}
see: http://blog.thoughtram.io/angularjs/2016/03/29/exploring-angular-1.5-lifecycle-hooks.html
and
https://toddmotto.com/angular-1-5-lifecycle-hooks#onchanges
If your HTML is like below you could do something like this:
<div ng-controller="ParentCtrl">
<div ng-controller="ChildCtrl">
</div>
</div>
Then you can access the parent scope as follows
function ChildCtrl($scope) {
$scope.isTrue= $scope.$parent.isTrue;
}
If you want to access a parent controller from your view you have to do something like this:
<div ng-if="$parent.isTrue">ele1</div>
<div ng-if="!$parent.isTrue">ele2</div>

React Nested loops

I have some grouped data that I would like to render like such:
RowGroupTableHeader
RowGroup1
RowGroup1-row1
RowGroup1-row2
RowGroup2
RowGroup2-row1
RowGroup2-row2
RowGroup3-row3
Normally, I would do a loop through the groups, and within each loop, I would have an internal loop to go through each of the rows.
However, because I'm working with accessibility, div structures are very strict. eg. you cannot just throw in a surrounding container around div[role=rowgroup]. i.e. each rowgroup needs to be at the same level.
As such, I cannot use the usual Array.map() nested within each other because after the first iteration, I am expected to close the return() and cannot start a new Array.map().
Anyone got any ideas how I can achieve this?
Is there a wrapper component out there that can render its contents without the wrapper? eg. {content}?
Thanks.
John.
I'm not sure I completely understand the question. But your last sentence leads me to believe that you want to to write a React class that renders its child directly, without wrapping it in an outer element like div? If so, that is possible, but ONLY if you pass a SINGLE valid React component in as a child.
The following should work:
class Foo extends React.Component {
constructor(props){
super(props);
}
render() {
if(React.Children.count(this.props.children) === 1){
// If there is only one child, return it directly, unwrapped
return React.Children.only(this.props.children);
} else {
// Otherwise, return all children wrapped in div
return <div className="foo">{this.props.children}</div>
}
}
}
...
// Later on...
<Foo><div>Hello, world!</div></Foo>
// Would render simply as
// <div>
// Hello, world!
// </div>
<Foo><div>Bar</div><div>Baz</div></Foo>
// Would render as
// <div class="foo">
// <div>Bar</div>
// <div>Baz</div>
// </div>

How to define place where dynamic components would be injected?

My components injected dynamical. But how to define place where they would be without any wrapping?
import { Component, ViewContainerRef, ComponentResolver } from '#angular/core';
constructor(
private apiService: ApiService,
private viewContainerRef: ViewContainerRef,
private componentResolver: ComponentResolver) {
}
create() {
this.componentResolver.resolveComponent(PieChart).then((factory) => {
this.viewContainerRef.createComponent(factory);
});
}
And i want to inject them in some DIV.
<div class="someClass">
<!--How inject them here? -->
</div>
There are two ways:
injecting the ViewContainerRef like in your question, then new components are added below this component
using a target element in your components template with a template variable like <div #target></div> and #ViewChild('target', {read: ViewContainerRef}) viewContainerRef:ViewContainerRef; to get the ViewContainerRef of this <div>. Added elements are again added below this <div>
createComponent() allows to pass an index. By default new components are always added at the end, but if you pass an index it is inserted at this position.
(not tested) with index 0 you should be able to add the new element before the target element.
If you add more than one component to the same ViewContainerRef you can pass an index to insert the new component before the elements added earlier.
In finale release, ComponentResolver is deprecated. Instead, We can use Compiler API to create ComponentFactory.
But how we can do this now?
I found this article http://blog.lacolaco.net/post/dynamic-component-creation-in-angular-2-rc-5/ but compiler does not have method compileComponentAsync.

Dynamic instantiation of Components?

Update: To clarify my sad verbiage below...
Given an array of JSON objects, a "Level" component and a "Sprite" component...
I'm stuck on the syntax to loop through the array and init a new "Sprite" for each JSON object and then add that "Sprite" to ... the template (?) of my "Level".
This is my "Level" template. I can hardcode the Sprite in and it works (as the image shows) but I'm scrambling to find the syntax to add an arbitrary number of Sprites.
<div>
<img src={ {imagePath}}/>
</div>
<div>
<app-sprite></app-sprite>
</div>
I'm a refugee Flex/Actionscript developer and am learning Angular 2. I "get" lots of it – but then I get stuck.
My little exercise here: based on some JSON (hard-coded now but later to come from a Service) is to populate a "Level" component with a background image, and then create and position some "Sprites" on the "Level".
Here's the way it looks now:
I've created a plunk of what I am doing. Where I am confused:
How do I dynamically create custom components the "angular" way? I've seen the tutorials with *ngFor to create li elements but the template for my "Sprite" component looks like this:
<div>
<img class="spriteFloater" src={{imagePath}}/>
</div>`
The above works if I hardcode the "imagePath" to a url – but if I try to use "eventData.imagePath" (where event data is a JSON obj) then it fails.
I can hard-code that a reference to that template into my "Level" ("app-sprite" tags) and it works but my attempts to generate "Sprites" on the fly have failed.
Also, I am trying to pass data to each "Sprite" and then use it in my template. I tried doing it through the constructor but that didn't work so a created a custom function to do it – and while it outputs the correct data to the console, the "Sprites" I am creating are not the ones being injected into the DOM.
Geez... sorry this is such a stupid, wordy post.
With Günter's nudge I was able to come up with this. I didn't know the syntax to use *ngFor correctly and then I had to figure out how to apply the passed in data to the style of the newly created sprites.
Guess I am not in Kansas Flex/Actionscript any more. This stuff is crazy... but I like it (I think).
<div>
<app-sprite *ngFor="let event of eventList" [eventData]="event"
></app-sprite>
</div>
import { Component, OnInit, Input } from '#angular/core';
import {Eventdata} from './eventdata'
#Component({
selector: 'app-sprite',
template:`
<div>
<img class = "spriteFloater" [src]="eventData.imagePath"
[style.left] = "eventData.x"
[style.top] = "eventData.y"
[style.background] = "eventData.id"/>
</div>`,
styles [`
.spriteFloater {
position: absolute;
background: black;
left: 50px;
top: 80px;
}
`]
})
export class Sprite implements OnInit {
#Input() eventData: Eventdata;
setEventData(data:EventData){
}
constructor() {
}
ngOnInit() {
}
}
I guess you just need to use
eventData?.imagePath
If you init data in ngOnInit() this is after Angular first tries to resolve bindings in the view. If eventData is null the access to imagePath throws. With ?. Angular accesses imagePath only when eventData is != null

Resources