In my Aurelia view I have a script tag from where I want to call a function from my view-model:
Page.html:
<template>
...
<script>
function beginEdit(args) {
console.log(args);
console.log(args.primaryKeyValue);
//In this place I want to call the sayHello() fuction
};
</script>
</template>
Page.js:
import {inject} from 'aurelia-framework'
import {HttpClient} from 'aurelia-http-client';
import {Router} from 'aurelia-router';
export class Licigrid{
constructor(){...}
activate(){...}
...
sayHello()
{
alert("Hello");
}
}
I tried to use inside my script tag ${sayHello();} but this calls the function immidiately when the page has loaded and not when the user has entered in the beginEdit() function.
I have reproduced this piece of code in Plunker.
Note that I am using a package that calls the beginEdit function by itself, so unfortunately I can not use .trigger(), .delegate(), or .call() inside my html tag which would solve my problem.
My question is: is there a solution to call the sayHello() function from my script tag?
The beginEdit function needs access to the App view model instance. We can use Aurelia's DI container to retrieve this:
var app = container.get(App);
app.sayHello();
Problem is we don't have access to the container within the beginEdit function. We can use a small hack to access the container:
var container = document.body.aurelia.container;
We also need the App constructor function because it's the key to retrieving the app instance from the container. We can use the System loader to load the module containing the App constructor function:
System.import('app').then(function(module) {
var App = module.App;
});
All together it looks like this:
function beginEdit() {
System.import('app').then(function(module) {
var App = module.App, // get the constructor function
container = document.body.aurelia.container, // get the container
app = container.get(App); // get the instance of App (the viewmodel)
app.sayHello();
});
}
Here's the working plunkr:
http://plnkr.co/edit/9c0oJmifjW5pXXdD06Hg?p=preview
Related
I'm trying to create a common functions file in NS8 app. One of the function has to do some http requests and then update the viewModel to show the loaded data. I'm not able to achieve this when the function is placed in a separate file. Here's basically what I have right now.
main.js
import { ApplicationSettings, Http, fromObject } from '#nativescript/core';
import * as commFunc from '../functions.js';
var page,
viewMode = new fromObject({
foo: 'bar'
});
export function onLoaded(args){
page = args.object;
page.bindingContext = viewModel;
commFunc.getPosition();
}
functions.js
import { ApplicationSettings, Http, Observable } from '#nativescript/core';
var viewModel = new Observable();
export function getPosition(){
// beep boop bap calculating
viewModel.foo = 'baz';
}
I also tried passing the viewModel as a parameter but that didn't work either.
Probably the cleanest way to do this is have getPosition return a value, and the caller assign the value into the viewModel, such as
viewModel.set("foo",commFunc.getPosition());
That said, I have functions that pass viewModel as a parameter. You'd need to remove the local declaration in function.js, though.
I have one question because I'm not sure if that possible. I have ReactJS project that included some javascript functions.
I found solution to call javascript function from react components with window object but is it possible to call function from reactcomponents in javascript script?
For example I have definied function in React component. Is it possible to call that function in javascript?
Thank you.
A function that is supposed to be used outside React application bundle should be exposed to global scope:
window.foo = () => { /* ... */ };
Then it can be accessed as such:
<script src="react-app-bundle.js"></script>
<script>
foo();
</script>
In case React application bundle is published as UMD module, it can export a function in entry point:
export const foo = () => { /* ... */ };
its namespace will be exposed to global scope when it's loaded via <script>:
<script src="react-app-bundle.js"></script>
<script>
ReactAppNamespace.foo();
</script>
This is the case for a lot of third-party React libraries, React itself exposes React global.
It's preferable to put all code that depends on React application internals to the application itself, so accessing globals is not needed.
i have a jquery code which gets executed at ngAfterViewInit()
//myComponent.ts
ngAfterViewInit() {
$(function () {
$('#myElement').click(function (e) {
//code working fine here
});
}
but i want to move it to an external myScripts.js to simplify the component
i tried moving tthe code to an external file then use import but this makes the script to be called only once so if i navigate to a child component (which erases the html element myElement with the onclick defined ) then back to the parent myElement is back without the onclick event
so the question is :
what is the best practice to use jquery/javascript with angular4
You need to export your function from myScripts.ts and then import it and call it within ngAfterViewInit().
After exporting correctly you should be able to do:
// app.ts
import { myInitFunc } from './myScripts';
ngAfterViewInit() {
myInitFunc();
}
// myScripts.ts
export function myInitFunc(): void {
$(function () {
$('#myElement').click(function (e) {
//do stuff
});
}
};
Take a look at export: https://developer.mozilla.org/en/docs/web/javascript/reference/statements/export
I'm currently working on a ReactJS project and I'm trying to come up with an effective way to namespace my code. The most obvious solution I have is to do the following:
let API = {
init: function() {
// Do some type of initialization here
}
makeACall: function() {
// Make a call
}
};
Previously, I'd make a file of functions each of which were exported like:
export function makeACall() {
// Make a call
}
And then I'd import it into another file using: import { makeACall } from 'utils/api';
However the problem here is that I may have another function in the imported file called makeACall. So what I'd like to do is namespace it. Question is: how do I import individual functions from an object/namespace or is this not possible?
Basically I'd like to patch functions that another function calls so that I can confirm they've been called. Is this possible in js? (I'm using Mocha/Chai/Sinon for testing).
A simplified version of what I'd like to do:
// in render.js
export helper = function() {}
export default = function() {
helper()
}
// in the render-test.js
import render, { helper } from 'render'
// what I'd like to to:
helper = sinon.spy()
render()
assert(helper.called, true)
It's possible, but it does require some rewriting, most notably the way you're calling helper in render.js.
Here's an example that works:
// render.js
export function helper() {}
export default function() {
exports.helper()
}
// render-test.js
import render, * as renderFuncs from 'render'
...
sinon.spy(renderFuncs, 'helper');
render()
assert(renderFuncs.helper.called)
The reason you need to call exports.helper() instead of just helper() is because the latter is a local reference to the helper function, which you can't access from the test file.
The exports object is accessible from the test file (it's given the name renderFuncs), so Sinon can change the reference to helper and wrap it with a spy.