Call function from the controller which is belonging to another - titanium

I have two controllers 'keyboard' is belonging to 'index' controller
I know I can call function in keyboard.js from index.js.
But How can I call the function in index.js from keyboard.js??
in this cae I would like to call wantToCall() from fromhere() function
my index.js
var KeyboardCon = Alloy.createController('keyboard',{});
$.KeyboardView.add(KeyboardCon.getView());
KeyboardCon.test() // I can call the function in keyboard.js from index.js
function wantToCall(){
//
}
my indes.xml
<Alloy>
<Window id="GameWin" class="container">
<View id="KeyboardView" />
</Window>
</Alloy>
my keyboard.js
function fromhere(){
I want to call wanToCall from here.
}
exports.test = function (){
}

I believe that will do it for you. You pass the $ into the keyboard controller to pass a reference so it can refer to the index controller in keyboard. Sorry didn't have time to test it.
index.js
var KeyboardCon = Alloy.createController('keyboard',{index: $});
...
exports.wantToCall = function(){
//
}
keyboard.js
var args = arguments[0] || {};
function fromhere(){
args.index.wantToCall();
}
Alternatively what I usually do:
index.js
Alloy.Globals.Index = $;
...
exports.wantToCall(){
//
}
keyboard.js
function fromhere(){
Alloy.Globals.Index.wantToCall();
}

Related

TestCafe: Selector within Selector

I work on a set of helpers for my page model.
This is how the DOM may look like:
<div id="parentA">
<div class="child yes">hello</div>
<div class="child">world</div>
</div>
<div id="parentB">
<div class="child no">hello</div>
<div class="child">world</div>
</div>
Now I want to inspect one of the.child elements within #parentA or #parentB.
import { Selector } from "testcafe";
fixture `children`
.page `http://localhost:8080/index.html`;
// an example of what I expect.
// this is not how i want to write tests.
test("hard-coded: child in A has class 'yes'", async (t) => {
const yesChild = Selector("#parentA .child").withText("hello");
t.expect((await yesChild.classNames).includes("yes"));
});
// helper function for the page model (in a shared module later)
function getParent(name: string) {
return Selector(`#parent${name}`);
}
// helper function for the page model (in a shared module later)
function getChild() {
return Selector(".child");
}
// this is how I want to write tests.
test("parametric-find: child in A has class 'yes'", async (t) => {
const parent = getParent("A");
const child = getChild().withText("hello");
const yesChild = parent.find(child); // there is no overload for find that takes another Selector.
t.expect((await yesChild.classNames).includes("yes"));
});
I think one solution could be a function like this:
async function withinParent(child: Selector, parent: Selector): Selector {
// how should I implement this?
}
Another solution could be a higher order function that creates the filterFunction:
test("parametric-find-descendantChild: child in A has class 'yes'", async (t) => {
const parent = getParent("A");
const child = getChild().withText("hello");
const yesChild = parent.find(descendantChild(child));
t.expect((await yesChild.classNames).includes("yes"));
});
function descendantChild(child: Selector): (node: Element) => boolean {
// how should I implement this?
}
but all the approaches I can think of lead to dead-ends.
parent and child could match multiple elements
there is no easy way to access an element selected by a selector in order to compare it to another selector
how do I compare Selectors?
functions/callbacks that operate on the Element level are executed in the browser. How cold I pass a Selector or the Elements matched by a selector into a browser function?
Well, should I write a feature request, or is there a smart way to do this?
You can chain Selector methods to achieve this.
function getParent(name) {
return Selector(`#parent${name}`);
}
function getChildren(selector) {
return selector.child('.child');
}
test(`parametric-find: child in A has class 'yes'`, async (t) => {
const parent = getParent('A');
const child = getChildren(parent).withText('hello');
await t.expect(child.classNames).contains('yes');
});

Mobx Observable not triggering changes

I've been working to implement MobX into one of my classes, and I believe I'm close to have it working but I'd really appreciate if someone can point out where I'm going wrong here.
Essentially when the refreshJobs() function runs, I'd like the render() function to execute again. From my understanding, if I updated the observable object jobs, the computed functions (renderSubmittedJobs(), renderInProgressJobs()) would run again producing new values, then the render function would run again since those values have been updated.
However, what happens with this code is that it updates this.jobs (wrapped in an action), but neither of the computed functions execute - and I believe that is why render isn't ran again either.
Does anyone know what might be causing this issue? I really appreciate any direction with this.
#observer
export default class Jobs extends React.Component<ScreenProps<>> {
#observable jobs = {};
#computed get renderInProgressJobs() {
inProgressJobs = [];
for (key in this.jobs) {
if (jobs[key].status === "in progress") {
inProgressJobs.push(this.jobs[key]);
}
}
return this.renderJobComponents(inProgressJobs);
}
#computed get renderSubmittedJobs() {
submittedJobs = [];
for (key in this.jobs) {
console.log(key)
if (this.jobs[key].status !== "in progress") {
submittedJobs.push(this.jobs[key]);
}
}
return this.renderJobComponents(submittedJobs);
}
renderJobComponents(jobList: Array) {
return jobList.map((jobInfo, key) => {
return (
...
);
});
}
#observer
async refreshJobs() {
jobs = await grabClientJobs(refresh=true);
await runInAction("Updating Jobs", async () => {
this.jobs = jobs;
});
}
#observer
async componentWillMount() {
jobs = await grabClientJobs();
runInAction("Updating Jobs", async () => {
this.jobs = jobs;
});
}
#observer
render(): React.Node {
console.log('in jobs now');
return <BaseContainer title="Jobs" navigation={this.props.navigation} scrollable refresh={this.refreshJobs}>
<Tabs renderTabBar={()=> <ScrollableTab />} tabBarUnderlineStyle={style.secondaryBackground}>
<Tab heading="In Progress" textStyle={style.tabTextStyle} activeTextStyle={style.activeTabTextStyle}>
{ this.renderInProgressJobs }
<Button full style={[style.secondaryBackground, style.newJob]}>
<Text>CREATE NEW JOB</Text>
</Button>
</Tab>
<Tab heading="Submitted" textStyle={style.tabTextStyle} activeTextStyle={style.activeTabTextStyle}>
{ this.renderSubmittedJobs }
</Tab>
</Tabs>
</BaseContainer>;
}
}
few mistakes here:
you can't re-assign another value to the observable variable, it'll destroy the observable. You need to mutate the observable. For example, you can directly assign values to existing properties or use extendObservable for assigning new properties to observable object.
If you use MobX < 4, adding new properties the observable object will not trigger changes because the properties are set when the observable object was created. extendObservable may work but it's also limited. Use observable Map instead.
#observer should be used for component class (or SFC), not member functions inside of the class

Can we use bootstrap modal backdrop as a standalone component

my question is that can i use bootstrap's modal plugin's backdrop as a separate standalone component, if i have to use backdrop for some other purpose.
If possible then how to use it.
Thanks in advance
You can't use bootstrap backdrop as a standalone component.
I have written the following js function, inherited from bootstrap, for using backdrop.
The function use jquery like bootstrap.
var backdrop = function () {
var that = this
var animate = 'fade'
that.$body = $(document.body)
that.__TRANSITION_DURATION = 300
that.__BACKDROP_TRANSITION_DURATION = 150
this.show = function (callback) {
var doAnimate = $.support.transition && animate
that.$backdrop = $(document.createElement('div'))
.addClass('modal-backdrop ' + animate)
.appendTo(that.$body)
if (doAnimate) that.$backdrop[0].offsetWidth // force reflow
that.$backdrop.addClass('in')
if (!callback) return
doAnimate ?
that.$backdrop
.one('bsTransitionEnd', callback)
.emulateTransitionEnd(that.__BACKDROP_TRANSITION_DURATION) :
callback()
}
this.hide = function (callback) {
if (that.$backdrop) {
var callbackRemove = function () {
that.$backdrop && that.$backdrop.remove()
that.$backdrop = null
callback && callback()
}
$.support.transition ?
that.$backdrop
.one('bsTransitionEnd', callbackRemove)
.emulateTransitionEnd(that.__BACKDROP_TRANSITION_DURATION) :
callbackRemove()
}
}
return this
}
and this is the code for using it:
function showBackdrop() {
var bd = new backdrop()
bd.show(function () { })
setTimeout(function () { bd.hide() }, 2000)
}
in both functions show and hide You have a callback for doing custom actions, exactly like bootstrap.
Note. You must set the show callback function for backdrop taking effect. For hide function it's no required.

durandal, pass parameters to widget during navigation

i have several singleton views in my SPA, each of these view contain the same widget.
When the view is activated i take some parameters from the activate callback and pass it to the widget and it works fine.
But if i navigate the second time into the view (with different parameters into the activate callback)
the activate method of the widgets is rightly not raised.
How can i pass the fresh data to the widgets ?
I tried to make the parameter observable and subscribe it into the widget (settings.params.subscribe) and it works, but i don't think it's a good solution.
This should be pretty simple assuming you are returning a constructor from your widget -
View model -
var thisWidget = new widget(someArbitraryData)
function createWidget() {
dialog.show(thisWidget);
}
// later
function updateWidget() {
thisWidget.refreshData(newArbitraryData);
}
Widget module -
define([], function () {
var ctor = function () {
var self = this;
self.data = ko.observable();
};
ctor.prototype.refreshData = function (newData) {
var self = this;
self.data(newData);
};
ctor.prototype.activate = function (activationData) {
var self = this;
self.data(activationData);
};
});

Injection in test when using Angularjs & requirejs

I am trying to use AngularJS with RequireJS currently, but I do not know how to make the test work with injection.
Without RequireJS we could,
Impl
PhoneListCtrl.$inject = ['$scope', '$http'];
var PhoneListCtrl = ['$scope', '$http', function($scope, $http) {
/* constructor body */
}];
Test
beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) {
$httpBackend = _$httpBackend_;
$httpBackend.expectGET('phones/phones.json').
respond([{name: 'Nexus S'}, {name: 'Motorola DROID'}]);
scope = $rootScope.$new();
ctrl = $controller(PhoneListCtrl, {$scope: scope});
}));
However, when we use RequireJS we may define the controller as following,
demoController.js
define(["dependency"], function() {
/* constructor body */
});
When using this controller, we add it as one of the dependencies and do not have a variable declaration.(Let me just use "Controller" as an example since we'd better call it "Service")
someJS.js
define(["demoController"], function(controller) {
controller.method();
});
My Question
How can we inject the $http, $scope(or something else) to the target controller or service for testing when using RequireJS(AMD)?
Any help would be highly appreciated.
I've done something similar:
/*global define, document */
define(['angular', 'jquery'], function (angular, $) {
'use strict';
return function () {
var $injector = angular.bootstrap(document, ['myApp']);
var $controller = $injector.get('$controller');
var myController = $controller('myController');
};
});
The idea is that angular.bootstrap returns an injector, which allows you to fetch a service.
I finally made it work by following.
angular.module('app').controller('MyController', ['$scope', 'dep2', function ($scope, dep2) {
$scope.method = function () {//do something};
}]);
We can use this controller in test cases like this:
inject(function($controller, $rootScope, dep2) {
scope = $rootScope.$new();
myController = $controller("MyController",
{
$scope : scope,
dep2: dep2
});
);