In an Aurelia Dialog, how to create routes for the viewModel? - javascript

When opening an Aurelia Dialog you usually pass it a viewModel.
This is how I'm currently doing this but it would be better if the path wasn't hard-coded here.
let lookupResponse = await this.dialogService.open(
{
model:
{
configuration: this.LookupConfiguration
caption: 'Select an item'
},
viewModel: 'App/Components/Lookup/LookupDialog'
});
I'd rather be able to reference the viewModel path like a route
let lookupResponse = await this.dialogService.open(
{
model:
{
configuration: this.LookupConfiguration
caption: 'Select an item'
},
viewModel: App.routes.components.lookupdialog
});
If you just add a Routes.js for the components and try to use it you get this error:
Uncaught (in promise) Error: Cannot determine default view strategy
for object.
So what needs to be added for this to work? A custom view strategy of some kind?

You can import the dialogs into your class and use them like this:
import { LookupDialog } from "app/components/lookup/lookup-dialog.ts";
export class Foo {
bar() {
let lookupResponse = await this.dialogService.open(
{
model:
{
configuration: this.LookupConfiguration
caption: 'Select an item'
},
viewModel: LookupDialog
});
}
}

Related

How to fix FlowRouter.getParam from being 'undefined'

I am adding a new page to a website, and I am copying the code that already exists and is currently working in the website. Why is the FlowRouter.getParam coming up undefined when it works everywhere else?
client/JobInvoice.js
import { Invoices } from '../../../imports/api/Invoice/Invoice';
Template.InvoicePage.onCreated(function(){
const user = FlowRouter.getParam('_id');
console.log(user);
this.subscribe('invoices', user);
});
lib/router.js
Accounts.onLogout(function(){
FlowRouter.go('home');
});
FlowRouter.notFound = {
action: function() {
FlowRouter.go('/404');
}
};
const loggedIn = FlowRouter.group({
prefix: '/secure'
});
loggedIn.route( '/invoice', {
name: 'invoice',
action() {
BlazeLayout.render('FullWithHeader', {main:
'InvoicePage'});
}
});
What am I missing?
FlowRouter allows you to define routes with dynamic attributes (path-to-regexp), which are often representing document ids or other dynamic attributes.
For example
FlowRouter.route('/invoice/:docId', { ... })
would define a route that matches a pattern like /invoice/9a23bf3uiui3big and you usually use it to render templates for single documents.
Now if you want to access the document id as param docId inside the corresponding Template you would use FlowRouter.getParam('docId') and it would return for the above route 9a23bf3uiui3big.
Since your route definitions lacks a dynamic property, there is no param to be received by FlowRouter.getParam.
A possible fix would be
loggedIn.route( '/invoice/:_id', {
name: 'invoice',
action() {
BlazeLayout.render('FullWithHeader', {main:
'InvoicePage'});
}
});
to access it the same way you do for the other templates.
Readings
https://github.com/kadirahq/flow-router#flowroutergetparamparamname
Here is what I ended up doing and it works.
loggedIn.route( '/invoice/:id', {
name: 'invoice',
action() {
BlazeLayout.render('FullWithHeader', {main: 'InvoicePage'});
}
});

How to override testClass methods with Siesta?

I'm using Bryntum Siesta for UI testing an ExtJS app. I've created a TestClass and aim to use its methods for different views. Whole actions of test are same only some specific things are changing such as package, view, grid names. Here is some snippets from Test Suite:
Main Test Class
var isDisplaying = 'Grid is displaying now.';
var collapseDesc = 'Collapse Navbar';
Class('Siesta.Test.ListScreen', {
isa : Siesta.Test.ExtJS,
methods: {
navigation: function (callback) {
var t = this;
t.chain(
{waitForCQ: 'treelist[itemId=navigationTreeList]'},
function (next) {
t.click('treelist[itemId=navigationTreeList]');
next();
},
{click: '>> treelistitem[_text=Package_Name]'},
{click: '>> treelistitem[_text=Package_Submodule]', desc: 'Package Submodule'+isDisplaying},
{click: '#main-navigation-btn => .fa-navicon', desc: collapseDesc},
function (next) {
console.log('navigation func log');
next();
},
callback
)
}
}
});
And this testClass calling from Package_Submodule and getting success:
describe('UI Testing: Submodule List Screen', function (t) {
//Extended method for navigation to submodule
t.it('Should open: Submodule Grid', function (t) {
t.chain(
{
navigation: t.next
}
)
});
});
The thing here is I want to call same TestClass method for another Submodule and override several things such as Package_Name and Package_Submodule. How can i be success to do this?
Thanks in advance
UPDATE through JackSamura's answer:
Dear #SamuraiJack I've refactored the Main Class (ListScreen) and inserted has attribute. As well modified the harness with config property but unfortunately it did not override myPackageName or mySubModule. Instead of i got this error:
Waiting for element ">> treelistitem[_text=packageName]" to appear
As well I've tried to use function arguments but it did not work too. Could you please give an idea why I couldn't override new values?
Main Class (Updated):
var isDisplaying = 'Grid is displaying now.';
var collapseDesc = 'Collapse Navbar';
Class('Siesta.Test.ListScreen', {
isa : Siesta.Test.ExtJS,
has : {
myPackageName : 'packageName',
mySubModule : 'subModule'
},
methods: {
navigation: function (callback) {
var t = this;
t.chain(
{waitForCQ: 'treelist[itemId=navigationTreeList]'},
function (next) {
t.click('treelist[itemId=navigationTreeList]');
next();
},
{click: '>> treelistitem[_text='+this.myPackageName+']'},
{click: '>> treelistitem[_text='+this.mySubModule+']', desc: this.mySubModule+isDisplaying},
{click: '#main-navigation-btn => .fa-navicon', desc: collapseDesc},
function (next) {
console.log('navigation func log');
next();
},
callback
)
}
}
});
index.js:
group: 'UI Tests',
items: [
{
group: 'Submodule List Screen',
testClass: Siesta.Test.ListScreen,
items: [
{
title : 'Submodule1',
hostPageUrl : localApp,
url : '02-ui-tests/02_01-submodule-list-screen/submodule1-list.t.js',
config : {
myPackageName : 'Package1',
mySubModule : 'Submodule1'
}
},
You can do it in 2 ways:
1) Add arguments to the "navigation" method:
// callback should be the last one
navigation: function (packageName, packageSubModule, callback) {
Probably self-explanatory
2) A bit more complex - add new attributes to your custom test class:
Class('Siesta.Test.ListScreen', {
isa : Siesta.Test.ExtJS,
has : {
// values goes into prototype, like in Ext
myPackageName : 'packageName',
mySubModule : 'subModule'
},
methods: {
Then you can refer to those attributes in "navigation" method as usual: this.myPackageName
Then, to override, you can either create a new test class (subclassing Siesta.Test.ListScreen) and re-define the attributes in it, or alternatively, use the config property of the test descriptor:
harness.start(
{
url : 'mytest.t.js',
config : {
myPackageName : 'value1',
mySubModule : 'value2'
}
},
...
)
Hint: To get the answer faster - post it to the Siesta forum: https://www.bryntum.com/forum/viewforum.php?f=20
UPDATE:
The errors you got are probably because "navigation" method is launched from the sub test (every "t.it()" or "t.describe()" section creates a separate "subtest"). Those sub tests won't have the config applied - it is applied only to the top-level test. One solution would be to copy the attribute values:
// in the "methods" of the custom test class
processSubTestConfig : function (config) {
var cfg = this.SUPER(config)
cfg.myPackage = this.myPackage
...
return cfg
},
But that is already advanced Siesta internals coding. Probably just using function arguments will be simpler..

Register Knockout.js component viewmodel from module in typescript

My viewmodel module has several classes, so I want to register a spesific class as component's viewmodel.
And it says: Component 'filter-table': Unknown viewModel value: [object Object]
This is what I have in my viewmodel module
module FilterVM {
export class FilterViewModel {
//some code
}
class FilterTableViewModel {
}
class AttributeTableViewModel {
}
class LayerAttributeViewModel {
}
}
export = FilterVM;
And this where I am trying to register
import FilterVM = require('Scripts/App/Components/AttributeTable/ViewModels/FilterViewModel');
ko.components.register('filter-table', {
viewModel: { require: FilterVM.FilterViewModel },
template: { require: 'text!Scripts/App/Components/AttributeTable/Views/FilterTableView.html' }
});
What is wrong with that?
SOLVED
The problem was here viewModel: { require: FilterVM.FilterViewModel }
Should be viewModel: FilterVM.FilterViewModel
require('Scripts/App/Components/AttributeTable/ViewModels/FilterViewModel');
You probably need to change this into a relative path. Even though TypeScript finds it at compile time ... the runtime library may not. Use something like require('../AttributeTable/ViewModels/FilterViewModel'); etc.

How to get the type of route path in Ember

If I have in the router map:
this.resource('detail', { path: '/detail/:type' }, function() {
...
});
And I retrive the currentPanth in my Ember Application code:
currentPath: '',
ApplicationController : Ember.Controller.extend({
updateCurrentPath: function() {
App.set('currentPath', this.get('currentPath'));
console.log('currentPath',App.currentPath);
}.observes('currentPath')
}),
When I navigate in my app, I get the route names by console, but when It is "detail" I get "detail.index". How can I get the type?
you only have access to the params in the route, ie. when you are defining your model:
App.Router.map(function() {
this.resource('photo', { path: '/photos/:photo_id' });
});
App.PhotoRoute = Ember.Route.extend({
model: function(params) {
return Ember.$.getJSON('/photos/'+params.photo_id);
}
});
Or you can also use paramsFor, also in the route only.
Depending on what you are trying to acomplish maybe query params suit better

Backbone routes doesn't work with Laravel

I dont't know exactly where the error/s is/are.
I'm doing a Single Page App, this is the context:
I have a resource controller in Laravel that watch this route "domain.dev/v1/"
Laravel serves the first page/view "/public/views/layouts/application.blade.php"
Mustache views are stored under "public/views/" and they are loaded synchronously when they are called by the Backbone Router (I've modified the "app/config/view.php" file to serve the views from bakcbone)
In backbone, the Router controls every URI change, even pushstate and the respective Mustache views. Everything seems to work fine, but if you type the direct URI for a user o list or users...you only see JSON returned by the server, not the corresponding Backbone View, in other words, I dont know Which is not doing the correct work, the Laravel Router or the Backbone Router. Or is it a Laravel configuration?
This is my code so far:
// app/routes.php
Route::group(['prefix' => 'v1'],function (){
Route::resource('users','V1\UsersController');
Route::get('/', function()
{
return View::make('layouts.application')->nest('content', 'app');
});
});
// app/controllers/V1/UsersController.php
namespace V1;
//import classes that are not in this new namespace
use BaseController;
use User;
use View;
use Input;
use Request;
class UsersController extends \BaseController {
public function index()
{
return $users = User::all(['id','email','name']) ;
}
public function show($id)
{
$user = User::find($id,['id','email','name']);
if(is_null($user)){
return array(
'id' => 0,
'email' => 'fake email'
);
}
return $user;
}
// public/js/namespaces.js
(function(){
window.App = {
Models : {},
Collections : {},
Views : {},
Router : {}
};
window.Templator = function (mustacheView){
return $.ajax({
url: '/views/'+mustacheView,
async : false,
type: 'GET',
}).responseText;
};
window.Vent = _.extend({},Backbone.Events);
})();
// public/js/backbone/router.js
App.Router = Backbone.Router.extend({
routes : {
'' : 'home',
'users' : 'showAll',
'users/:id' : 'showUser',
'login' : 'showLoginForm'
},
home: function (){
Vent.trigger('home:index');
},
showAll : function (){
Vent.trigger('users:showAll');
},
showUser: function (id){
Vent.trigger('users:show',id);
},
showLoginForm : function (){
Vent.trigger('login:form');
}
});
// public/js/app.js
$(function() {
$(document).on("click", "a", function(e){
var href = $(this).attr("href");
if (href != '#') {
e.preventDefault();
Backbone.history.navigate(href,{trigger:true});
}
});
new App.Views.AllUsers;
new App.Views.Index;
new App.Views.Login;
new App.Router;
Backbone.history.start({
pushState: true,
silent: true,
root: '/v1'
});
});
So, if I type this URI "domain.dev/v1/users" on the nav bar, shows list of users in JSON and the view associated in backbone is not displayed.
Any suggestions?
Have a look at my answer I just gave in a similar question about Angular: Angular and Laravel
In the text, just mentally replace Angular with Backbone.
How to pass the route from Laravel to Backbone:
The base view, that is returned from Laravel for the '/' route needs to have something like this somewhere in its <head> before backbone.js is included:
<script>
var myRoute = "{{ $route }}";
</script>
This blade template creates a Javascript variable. Then, after you declared your routes in Backbone, add this:
Backbone.history.start(); // You should already have this line, so just add the next one
App.nav.navigate(myRoute);
This should do the trick.

Categories

Resources