Is there a way to dynamically add a 2 way binding [(somemodel)] property to a Host element in Angular 4 ?
<my-comp></mycomp>
We would like to replace the above markup to look like
<my-comp [(somemodel)]="modelvalue" ></mycomp>
dynamically at run time. We are aware the #HostBinding does not support this, as the most common examples we have seen are adding class or attributes to host.
Is there any way to replace the host element like this using Angular 4 ?
We are open to dynamically loading templates/components if someone can point us to the right direction.
In Angular 1, we used to replace the host element markup with our text and do a $compile(scope). Is there a similar approach in Angular 4 using dynamic loading ?
I think what you're looking for is #Input in Angular 4. It allows you to define a variable on your component and receive it's value from the HTML. Here are the Angular Docs on Input/Output
And a quick example
In your component, import 'Input' from Angular Core
import { Input } from '#angular/core';
Then, define your input variable. Here, I'm for a loading variable that is a boolean.
#Input() loading:boolean = false;
Then, in your HTML define the binding.
<loader [loading]="loading"></loader>
Remember that the 'loading' inside of the brackets will match the name of your input variable.
Related
I have a lightning-card in lightning web component (LWC) and want to set the label attribute with two different variables. Although this can be done through the controller but I want to do this in html file itself.
As in the code snippet, I am assigning {cardTitle} as a title, but I have another variable {totalCount} and want to concatenate the totalCount along with the cardTitle here. So lightning-card should have title like "{cardTitle}{totalCount}".
<lightning-card title={cardTitle}></lightning-card>
//In Controler js
#track cardTitle = 'Student details';
#track totalCount = 0; //This will be set by the apex controller later and will have dynamic number
When I try below code
<lightning-card title={cardTitle}{totalCount}></lightning-card>
It shows error as
multiple expressions found
.
No. You can only do it in controller JavaScript file.
I love part of the answer on SF stackexchange so I'm going to quote it here:
Your concerns about separating UI from controller logic do not apply
here as this is not a "controller". That MVC pattern is an Aura-ism.
This is the code which drives your component's functionality so it
makes sense that your JS would know about class names.
It's different but think about it that way - it'll let you write a proper unit test for the JavaScript. How you'd test logic that exists only in HTML layer? Or only in Visualforce page markup?
You can have only one expression. If you read documentation like https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.reference_directives
you'll see
The expression can be a JavaScript identifier (for example, person) or dot notation that accesses a property from an object (person.firstName). The engine doesn’t allow computed expressions (person2.name['John']). To compute the value of expression, use a getter in the JavaScript class.
Hi i am very new to angularjs web development with typescript and really stuck with a problem. I dont think it should be a hard problem yet i have spent two days on it.
I am trying to figure out how i can pass the value of an ng-repeat from a list to a child component when it's being constucted or initiated.
What i mean is, if i have a list([1, 2, 3, 4]) from the parent component that is used to generate 4 child components is there a way for each of the child components to assign a variable "id" to the value associated to the value of the repeat.
for example
<span ng-repeat=variable in list>
<child-tag></child-tag>
</span>
Is it possible to somehow pass the variable into the constructor of the component from the tags or something?
Just to reiterate, I have coded this using typesccript with angularjs not angular 2.
Cheers in advance for the help.
And sorry in advance for what is probably a very simple answer but cant find it anywhere.
You can pass the data from parent to child component using Input.
Inputs should be using < and # bindings. The < symbol denotes one-way bindings which are available since v1.5.
=: Two way binding. It uses dirty checking and can cause latency. It also watches bound properties in the component scope.
So if you need to pass some data to child component, you need to bind some attribute value to it . Ex:
<span ng-repeat="variable in list">
<child-tag variable-name="variable.name" ></child-tag>
</span>
Inside your child component declaration bind these values so that you can access them:
angular.module('myApp', []).component('childComponent', {
bindings: {
variableName: '<'
},
controller: ....
You can access these values inside your component class using: this.variableName
You can choose to have one way or two binding as needed and can have as many objects/attributes passed to child as you want.
Hi all..
referring to ngRoute,
i created a single page application but would like to apply different css rules to each sub-page like background image
how can i do that?
i assigned a different controller to each sub-page
and in the link tag i used ng-href and {{name}}.css to tell the browser to grap the correct css file where is name is giving the value of the file name and attached to the scope inside the corresponding controller.
is there a need to use more than one ng-controller ?
here is the view : http://shireefkhatab.github.io/imax-design
and my code : https://github.com/shireefkhatab/imax-design
hope to get a response
thank you all in advance.
Reefo.
You can include those styles in your template (views) or make separate route for styles, add its view in head section and then change state from your controller using $state.go('where.ever.you.want.to.go');
I am working on a project in ExtJS 4.2 written in the MVC pattern. I need a reference to a specific item inside MyViewport (extended from the class Ext.container.Viewport). The item which needs to be referenced from within the controller has the Class MyPanel (extended from "Ext.Panel"). Problem is there are several items with the same class, so simply doing a standart ExtJs-component-query like,
//inside myController.js
refs: [
...
{ref: 'specificItem', selector: 'MyViewport_alias > myPanel_alias'},
...
]
wont get me a reference to the item. Thats why i thought of retrieving the reference by something like this, since the items using MyPanel-class have a property title:
//inside myController.js
refs: [
...
{ref: 'specificItem',
selector: 'MyViewport_alias > myPanel_alias > title="title of specific item"'},
...
]
But i coulnd't find any examples on retrieving items as references by using their properties as parts of the component query other than this.
Has someone experience with this kind of problem?
Component queries in ExtJS are very similar to CSS query selectors. You could find a component by a specific property with syntax similar to: "... > [title=My Component Title]" - that said, using the "title" sounds like really bad practice.
At worst, as a visible part of the user-interface it's very sensitive to change - easily breaking your application and at best it immediately limits your application's language-support and configurability.
Ideally you should be utilising the itemId property as a more robust way of referencing components.
» fiddle
I hadn't noticed that 4.2 didn't support attribute selectors - the component query functionality seems to have always drawn inspiration from CSS though, so unfortunately if it's only a recent development it doesn't look like there's any way to do what you want using this method.
You'd have to manually fetch the component and/or create your own reference. You can select by xtype / alias in 4.2 and then apply a filter to the result, for example:
Ext.Array.filter(Ext.ComponentQuery.query('panel'), function(x){
return !!x.title.match('Sub Panel 2');
}).shift();
( Obviously no use in a controller's refs )
» fiddle
... this is however ugly - all the more reason to use itemId's properly. There was already an example of this in action in the first fiddle. All you need to do is assign an alphanumeric string (no spaces) to the property - these don't strictly need to be unique but it's generally preferable. Then in your selector simply prefix a hash # in front of the string which indicates to the engine that you are looking for a component with a specific ID.
itemId selectors definitely work in 4.2 so without seeing your code I can only speculate as to what the problem is. In your post you are using > which narrows the query to direct descendants only. Are you absolutely sure that the component you are looking for is a child of myPanel_alias and not wrapped up in another container? i.e.
"myPanel_alias #myItemId" <-- try this
"myPanel_alias > #myItemId" <-- instead of this
I'm new to AngularJS and have been assigned a maintenance task on an app we've inherited (originally developed for us by a third-party).
At the left of a header row in a table is a small button showing either a plus (+) or minus (-) symbol to indicate whether it will expand or collapse the section when clicked. It does this using ngClass as follows.
ng-class="{false:'icon-plus',true:'icon-minus'}[day.expanded]"
I have to remove the button when there is no data in the section and thus no ability to expand. There is already a class (.plus-placeholder) for this and I was wondering if the expressions that ngClass uses can be nested to allow something like this
ng-class="{false:'plus-placeholder',true:{false:'icon-plus',true:'icon-minus'}[day.expanded]}[day.hasTrips]"
which would allow me to add a hasTrips property to day to accomplish the task.
If this is not possible I think I will need to add a property something like expandoState that returns strings 'collapsed', 'expanded' and 'empty'. so I can code the ngClass like this
ng-class="{'collapsed':'icon-plus','expanded':'icon-minus','empty':'plus-placeholder'}[day.expandoState]"
And perhaps this is a cleaner way to do it in any case. Any thoughts/suggestions? Should it be relevant, the app is using AngularJS v1.0.2.
You certainly can do either of the two options you have mentioned. The second is far preferable to the first in terms of readable code.
The expandoState property you mention should probably be a property or a method placed on the scope. Your attribute would then read something like
ng-class="{'collapsed':'icon-plus','expanded':'icon-minus','empty':'plus-placeholder'}[expandoState()]"
To put this method on the scope you would need to find the relevant controller. This will probably be wherever day is assigned to the scope. Just add
$scope.expandoState = function() {
// Return current state name, based on $scope.day
};
Alternatively, you could write a method on the controller like
$scope.buttonClass = function() {
// Return button class name, based on $scope.day
};
that just returns the class to use. This will let you write the logic from your first option in a much more readable fashion. Then you can use
ng-class="buttonClass()"