Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible incompatibility of function.depends pattern with TypeScript #396

Closed
BorisMoore opened this issue Jan 4, 2018 · 10 comments
Closed
Labels

Comments

@BorisMoore
Copy link
Owner

See https://stackoverflow.com/a/47859851/1054484.

@BorisMoore BorisMoore changed the title Possible incompatibility of funncion.depends pattern with TypeScript Possible incompatibility of function.depends pattern with TypeScript Jan 4, 2018
@ClaudeVernier
Copy link

Hello,

Thank you for your answers and for creating this issue, I did find a web site where I can create a working example in TypeScript!
https://codepen.io/ClaudeVernier/pen/JMOJOR

In this pen, I tried to explain the issue with my latest findings, it looks like it might be Visual Studio that is wrong.

I can also provide files if useful for you.

Regards,
Claude

@BorisMoore
Copy link
Owner Author

Thanks Claude. I will come back to this at some point, when I look more closely at TypeScript support for JsViews and JsRender. It's very helpful to have this example...

@ClaudeVernier
Copy link

Dear Boris,
I hope you are doing well.

I am coming back to this project where the function .depends doesn't work for me in VS 2017 using TypeScript. Would you, by any chance, have some news that would bring light upon this issue ?

Thanks and regards,
Claude VERNIER

@BorisMoore
Copy link
Owner Author

Hi Claude,
Yes, thanks - I'm doing well. I am working on some major feature improvements in JsViews, and won't be able to get to the Typescript question for a while. I was only planning to look at Typescript support as a last step before (or just after) bringing out the V1.0. See #175. Sorry not to be able to get to it sooner...

@BorisMoore
Copy link
Owner Author

BorisMoore commented Nov 23, 2018

@ClaudeVernier

Hi Claude - I have finally completed work on V1.0 - to be published soon. I also have completed TypeScript declaration files for jsrender and jsviews:

Note that jsviews.js includes the code from jsrender.js, jquery.observable.js and jquery.views.js. So no need to load jquery.observable.js in your codpen sample. (See https://www.jsviews.com/#download)

Here is a fork of you codepen that includes the TypeScript declaration code, and fixes your issues.

https://codepen.io/borismoore/pen/wQmPoz

And here is another which tests loading jsrender and jsviews d.ts files from a server (you can replace with your own URLs):

https://codepen.io/borismoore/pen/wQmXRB

After publishing V1.0 I will publish the d.ts files to definitelyTyped.org.

The fix for your sample was to move the setting of .depends to before calling tmpl.link:

(this.GetName as JsViews.GetSet).depends = "~root.activeLanguage";
// Or  (this.GetName as JsViews.GetSet).depends = [this, "activeLanguage"];

tmpl.link("#optionsTmpl", this);

BTW the casting of this.GetName to as JsViews.GetSet is to avoid the TypeScript 'error'. But getting the error does not really matter since the compiled .js is still correct, and works just the same...

Let me know if you see other issues (e.g. with the TypeScript definitions)...

@BorisMoore
Copy link
Owner Author

Closing this issue, since it is not a JsViews bug. (Also it seems to be fixed by the suggested cchange to your code).

@ClaudeVernier
Copy link

ClaudeVernier commented May 13, 2019 via email

@BorisMoore
Copy link
Owner Author

Thanks Claude, glad to hear back from you...

@jonathantisseau
Copy link

Hi, I know this issue is closed but I found it while searching the same issue.
Another solution to your problem is to go with a decorator :

/**
 * JsViews Depends decorator
 * Add the value to the depend property of the target
 * Even if it can work with a getter, JsViews doesn't allow it and, even if the initial display works, it won't be refreshed.
 * @param {string|any[]|JsViews.dependsFunction} value The depends path(s) or function
 */
export function depends(value: string | any[] | JsViews.dependsFunction) {
	return function (target: any, propertyKey: string, descriptor: any) {
		if (!descriptor) {
			descriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
		}
		let func = descriptor.get || descriptor.value;
		if (func && typeof func === "function") {
			func.depends = value;
		}
	};
}

An then you can do something like this

class UnchartedGame {
    ...
    @depends("~root.activeLanguage")
    // or @depends((data, callback) => ["~root.activeLanguage"])
    GetName(harbor: IHarbor): any {
        return harbor.name[(this as IJSViewsContextHolder).ctx.root.activeLanguage];
    }
    ...
}

The main advantage of this solution is to keep the function definition and its depends definition together.
The inconvenients are that you can't use variables in this context and you can't use a getter because JsViews doesn't allow it.

Here is the working codepen : https://codepen.io/jonathantisseau/pen/NWKRvOQ

I'm new to JsViews so I haven't tested it in every possible ways.

@BorisMoore
Copy link
Owner Author

Thanks for the suggestion and code, @jonathantisseau!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants