car.ts has "isNewCar" variable in "export class Car{}", and I need to export the "isNewCar" variable to another component carSale.ts which is in a different directory, and not in the same module. Do I have to add the car.ts template to the carSale.ts file and add the "isNewCar" as input?
edit: car.ts has export class Car{ isNewCar:boolean = false; } and car.ts is a component. carSale.ts is also a component but it is not in a same/shared module as car.ts I need carSale.ts, and eventually carSale.ng.html to get access to the isNewCar variable. So, can you tell me how I would use the viewChild decorator or anything else in carSale.ts to access that variable? I would ideally not want to make a shared module though but if I have to, I can.
you can extend the Car class like,
export class CarSale extends Car {
ngOnInit(){
this.isNewCar = true;
}
}
By extending the Car class, you will be able to access the isNewCar property from the CarSale class
Need some more information about the use case. Is the car.ts a component or a model ?
If the car.ts is a model you should aggregate it in your carSale.ts component or, if really necesary, make it globaly available with a service.
If car.ts is a component with his own template, then you can acces the value with the output event emitter or by using a viewChild decorator.
There are other way to share variables but the above is the more common.
car.ts :
/*
* This is a POJO
*/
export class Car{
isNew: boolean;
}
car-sale.component.ts :
export class CarSale {
car: Car; // Car is aggregate into CarSale
ngOnInit(){
car = new Car();
car.isNew = true;
}
}
car-sale.component.html
<-- just use your car object like this --!>
<div *ngIf="car">Is the car new ? {{ car.isNew }}</div>
Related
Basically I have a ViewMaster with many many Functions that gets somewhere in a wrapper => components executed
Now I want to have a different but mostly the same View that needs some extra Functions. Now 2 states are changing its type from
interface ViewState {
something:something
...
}
to
interface NewViewState extends ViewState {
change:change
}
But how am I able to do this.
My ViewMaster looks like this
class ViewMaster extends React.Component<ViewProps,ViewState>{}
and my new View
class ViewNew extends ViewMaster
But how am I able to set a new ViewState generic?
EDIT: Thinking about it, I can simply change the interface ViewState
to
interface ViewState {
change:change|something
}
But still It would be intresting to know
There are a number of ways you can do this. Given that your base component is a React Component and it already has parameterization I would do something like this:
class ViewMaster<P = ViewProps, S = ViewState> extends React.Component<P, S>{}
and then
class ViewNew extends ViewMaster<ViewProps, NewViewState>{}
It shows an error with the template,
Errors:
Property 'result' is private and only accessible within class 'upperCaseComponent'
Property 'mymessage' is not declared in 'upperCaseComponent'
my html
<input type="text" [(ngModel)]="mymessage"
<button (click)="clickMe()"> send</button>
<br><br>
<h1>{{result | json}}</h1>
my component.ts
import {Component} from "#angular/core";
export class MyComponent {
private result: any;
constructor()
}
So here the error say it not able to find variable 'mymessage' in uppercase.component.ts
export class UpperCaseComponent {
public results: any; // Change it private to public
public mymessage: any;
}
If you are trying to access variable within template you need to declare it as public as if you declare it as private it would be accessible only within class
welcome to SO.
Regarding your question, could you please give me a confirmation on the below points so that I can help you in a better way.
Can you please edit the question and post the component code here. (You can mask the sensitive data here).
Please check if you are using binding data is marked private?
Try like this:
export class upperCaseComponent {
result: any;
mymessage: String;
... // other code goes here
}
UpperCaseComponent.ts has result field as private, uppercase.component.html cannot access it so make result field as public.
As for myMessage field as it's not defined anywhere in the UpperCaseComponent.ts I assume you want to set it from the parent component, then create an #Input myMessage field in UpperCaseComponent.ts and use it in the template. Bind this from parent component wherever you want to use this UpperCaseComponent
I want to tell Typescript that one member of one of my class is coming from another class.
For example:
Class Main{
getDataFromChild(data){
console.log(data)
}
}
Class Child{
getDataFromChild: Main.getDataFromChild //<== something like this
}
Use Case
My use case is React parent passing method down to React child. I want my IDE to navigate to Parent method decleration when I click on the passed method inside child.
export default class Parent extends Component {
simplifiedFunction (value) { // Line A
console.log(value)
}
render () {
return (
<div>
<Child
simplifiedFunction = {this.simplifiedFunction}
/>
</div>
)
}
}
export default class Child extends Component {
render () {
return (
<div>
<h1 onClick= { () =>
this.props.simplifiedFunction(<SomethingThatYouWantToPassIn>)//<== ctrl + click on simplifiedFunction should take me to its definition in parent class (Line A)
}
> Something</h1>
</div>
)
}
}
You could define an interface (named or anonymous):
interface SharedFeature {
sharedFunction: () => void;
}
and then implement it on the parent
class Parent extends React.Component implements SharedFeature {
sharedFunction() { ... }
render() { return <Child sharedFunction={sharedFunction} />; }
}
finally you can use the interface as part of the Child component's props
class Child extends React.Component<SharedFeature, {}> {
render() {
return <div>
{this.props.sharedFunction()}
</div>;
}
}
When using Component class you can take advantage of it's two generic arguments, first one defined the interface of props and the second one defines interface of the state. You can either use SharedFeature interface directly or extend another interface by it and then use that interface for props.
I dont know what kind of IDE you use but usually in this case when you do "Go to implementation" the IDE should succesfuly locate class Parent as it implements the interface that defines the function sharedFunction();
Beware that if you do "Go to definition" you WILL be taken to the declaration of the interface SharedFeature. If you want to use "Go to definition" nontheless (antipattern)use the class Parent itself as type for class Child's props. However this also makes Parent's method render() and ANY OTHER MEMBERS part of the props aswell.
I don't think this will work the way you are hoping it will. Namely your <Child/> component shouldn't have any awareness as to what passed it the simplifiedFunction prop. In your case, you happen to be passing it in from <Parent/>, but you should be able to pass in any function that satisfies the contract of the function. Imagine you had 3 other components that passed in different functions, your child component should never have to care about that.
Your question says that you "want to tell Typescript that one member of one of my class is coming from another class." This is an XY problem, in the sense that you say you want to do one thing (copy a method from one class to another) but your goal is something else (passing a method to a React component), and this should be done a different way.
Luk's answer gives a good solution for your actual use case. In my answer I'll address the original question about copying a method from one class to another, and explain why doing that is not a good solution.
Strictly speaking, the answer is simple:
class Main {
foo(): void {
console.log('bar');
}
}
class Child {
foo = Main.prototype.foo;
}
However, do not do this. You will be arrested by the OOP police, and sent to OOP jail.
It almost always doesn't make sense to do this. A method on the class Main may make use of properties that are defined in that class. Child is not a subclass of Main so it does not necessarily have the same properties. What if it's like this?
class Main {
x: string = 'bar';
foo(): void {
console.log(this.x);
}
}
class Child {
foo = Main.prototype.foo;
}
Now what is new Child().foo() supposed to do? A Child has no x property to log.
If the foo method really doesn't access any of Main's properties, and this fact is part of Main's contract (as depended on in the Child class), then the method should be static and the Child class should invoke it as Main.foo().
If the foo method does access some of Main's properties, but only properties shared by the Child class, then you should design your class hierarchy so that either Child is a subclass of Main, or so that those properties and the foo method belong to a common superclass, so that they can be shared by inheritance.
I have a dart server running on AppEngine and a Dart-Polymer client. The idea was to share common logic, such as the models. However, there is a little problem. Usually you would make your model-Classes extend JsProxy and than annotate all relative fields with #reflectable in order to use them in data binding. Unfortunately the model which works with AppEngine's datastore already inherits from Model. Besides that, I am not sure whether dart:js is available on the server. Hence, I have to find another way to make my model reflectable for the UI.
Annotating Project#name with #reflectable didn't work. Same empty div as output.
When including JsProxy in the model:
The built-in library 'dart:html' is not available on the stand-alone
VM.
Any ideas?
#Kind(name: 'Project', idType: IdType.Integer)
class Project extends Model {
#StringProperty(required: true)
String name;
}
#PolymerRegister('project-list')
class ProjectList extends PolymerElement {
#property List<Project> projects;
ProjectList.created() : super.created();
ready() {
fetchProjects();
}
}
<dom-module id="projects-page">
<template>
<template is="dom-repeat" items="{{projects}}">
<div>{{item.name}}</div>
</template>
</template>
</dom-module>
Output:
<div></div>
This is a known issue https://github.com/dart-lang/polymer-dart/issues/664
The best workaround so far is to use proxy objects where the annotations are applied and that wrap the shared model classes.
class FooProxy extends JsProxy implements Foo {
final Foo model;
FooProxy(this.model);
#reflectable
int get bar => model.bar;
set(int value) { model.bar = value}
}
I'm trying to create a rich data model for an AngularJS application and I would like for my model to inherit from Array<BaseModel>. I haven't found a way to do this (with confidence) yet.
In pseudocode this would be something like:
// NOT REAL CODE. DOES NOT WORK
class BaseModel {}
class Person extends BaseModel {}
class People extends Array<Person> {
constructor(private promise:Promise) { }
$unwrap(promise) {
promise.then((response) => {
response.data.map((person) => {
this.push(new Person(person));
});
});
}
static $load() {
/* do some ajaxy thing and unwrap the promise right onto the
the new instance of this rich model */
return new People(promise);
}
}
The reason I would like something like this is that now I can bind this model directly to my view and get updates on the fly.
Any thoughts on extending from Array?
At this point it time it is not possible to inherit from Array in TypeScript. It is best to unwrap into a public array field and use this field to bind to the UI. It resolves into the same functionality and remove the necessity of inheriting from Array.