I want to display the records, but when I test it to display the data on console use record.get(''), it not work . even I tap the static code console.log('some thing'). It also cant display on my console.
The code in my controller:
it near the //-------here it is
Ext.define('ylp2p.controller.addtab',{
extend: 'Ext.app.Controller',
config: {
refs: {
myTabPanel: '.makemoney #tabfirst',
},
control: {
myTabPanel: {
activate: 'onActivateTabPanel',
activeitemchange: 'onActiveItemChangeTabPanel'
}
}
},
launch: function(){
var products = Ext.getStore('productstore');
products.filterBy(function(record, id){
return record.get('loanname') === 'xixi22';
});
},
onActivateTabPanel: function(newActiveItem, viewport, oldActiveItem, eOpts) {
//test
console.log('hello the activatetabpanel is fire!');
//end test success
var tabs = Ext.getStore('loanliststore');
tabs.each(function(record) {
console.log('hello come on');//---------------------here it is
newActiveItem.add({
title: record.get('loanname')
});
console.log('');
});
},
onActiveItemChangeTabPanel: function(cmp, value, oldValue, eOpts) {
console.log('hello this is the activechangepanel is fire!');
var products = value.getStore();
products.clearFilter(true);
products.filterBy(function(record, id) {
return record.get('loanname') === value.getTitle();
});
}
});
Check by tabs.getCount() if it is greater then 0 then it should work. If not means there is no data populated in your store.
Related
I'm having the search column with checkbox along with folder names. when I click the checkbox of corresponding folder, it will show their items. As well as when I click on multiple checkbox it will show their corresponding items. But when I uncheck the folder, the corresponding items doesn't remove. So I need the hard reload or refresh when I check or uncheck the checkbox or need to clear the cache for every check or uncheck.
Here is my Code:
Checkbox: Core.component.Checkbox.extend({
click: function () {
var ret=null;
var nav = this.get("controller").get('selectedNavigator');
ret = this._super.apply(this, arguments);
var states=null;
Ember.run.schedule('sync', this, function () {
Ember.run.schedule('render', this, function () {
states = this.get('parentView.itemStates');
var values = Object.keys(states).filter(function (key) {
if(states[key]){
return states[key];}
else{return;}
});
if (values.length === 0) {
Core.Action('core:contentHome', {});
} else {
this.set('parentView.model.values',values);
nav.publish();
}
});
});
return ret;
}
}),
For the Publish:
publish: function () {
var currentResultSet = this.get('resultSet'),
ctl = this.get('controller'),
form = ctl.get('formModel'),
resultSet,
data = form.sleep(2000);
if (Object.keys(data).length === 0) {
Core.view.Menu.create({
anchor: $('*[data-class-name="Core.Tab.Content.Controller.NavigationRefresh"]'),
model: [
Core.model.Menu.Item.create({
label: "Please select something to search.",
icon: 'dialog_warning'
})
]
}).show();
return;
}
resultSet = form.send();
ctl.set('loadState', 'loading');
ctl.set('resultSet', Core.model.BlankResultSet.create({
loadState: 'loading',
tabContext: Ember.get(form, 'resultSet.tabContext')
}));
resultSet.fail(function (err) {
ctl.set('loadState', 'loaded');
console.log(currentResultSet);
ctl.set('resultSet', currentResultSet);
}).always(function () {
ctl.set('loadState', 'loaded');
});
},
I am trying to build a menu between categories. If a category has a sub-category it returns a value that says has_subCategory as boolean 0/1.
<template>
<select><slot></slot></select>
</template>
<script>
export default {
props: ['value',
'hasSubCat'],
watch: {
value: function(value, hasSubCat) {
this.relaod(value);
this.fetchSubCategories(value, hasSubCat);
}
},
methods: {
relaod: function(value) {
var select = $(this.$el);
select.val(value || this.value);
select.material_select('destroy');
select.material_select();
},
fetchSubCategories: function(value, hasSubCat) {
var mdl = this;
var catID = value || this.value;
var has_subCat = hasSubCat || this.hasSubCat;
console.log("has_subCat:" + has_subCat);
mdl.$emit("reset-subcats");
if (catID) {
if (has_subCat == 0) {
if ($('.subdropdown').is(":visible") == true) {
$('.subdropdown').fadeOut();
}
} else {
axios.get(URL.API + '/subcategories/' + catID)
.then(function(response) {
response = response.data.subcatData;
response.unshift({
subcat_id: '0',
subcategory_name: 'All Subcategories'
});
mdl.$emit("update-subcats", response);
$('.subdropdown').fadeIn();
})
.catch(function(error) {
if (error.response.data) {
swal({
title: "Something went wrong",
text: "Please try again",
type: "error",
html: false
});
}
});
}
} else {
if ($('.subdropdown').is(":visible") == true) {
$('.subdropdown').fadeOut();
}
}
}
},
mounted: function() {
var vm = this;
var select = $(this.$el);
select
.val(this.value)
.on('change', function() {
vm.$emit('input', this.value);
});
select.material_select();
},
updated: function() {
this.relaod();
},
destroyed: function() {
$(this.$el).material_select('destroy');
}
}
</script>
<material-selectcat v-model="catId" name="category" #reset-subcats="resetSubCats" #update-subcats="updateSubCats" id="selcat">
<option v-for="cat in cats" :value="cat.cat_id" :hasSubCat="cat.has_subCat" v-text="cat.category_name"></option>
</material-selectcat>
The data looks like this:
cat_id:"0"
category_name:"All Subcategories"
has_subCat:0
What I dont understand is that console.log("has_subCat:" + hasSubCat); prints out different values each time I change the select. It should only display 0 or 1
Watcher in vue.js is supposed to be used in order to watch one value, but you can fulfill your requirement with help of computed.
export default {
props: ['value',
'hasSubCat'],
watch: {
/* without this, watcher won't be evaluated */
watcher: function() {}
},
computed: {
watcher: function() {
this.reload(this.value);
this.fetchSubCategories(this.value, this.hasSubCat);
}
},
...
}
I also made a simplified working fiddle, you can have a look.
You are assuming that the second parameter of your watch function is hasSubCat which is not the case. While the first parameter of the value watch function represents the new value of the property, the second parameter is actually the old value of the watched property. Try this out to understand more.
watch: {
value: function(value, oldValue) {
console.log('new value:', value)
console.log('old value:', oldValue)
}
}
So to watch both of value and hasSubCat, you can do something like this:
watch: {
value: function(newValue) {
this.reload(newValue)
this.fetchSubCategories(newValue, this.hasSubCat)
},
hasSubCat: function(newHasSubCat) {
this.reload(this.value)
this.fetchSubCategories(this.value, newHasSubCat)
}
}
I have a regular tree with elements. What i want to do is following:
When I reload the page, the selected item must be the same as before ( I select only 1 item in the tree).
For example, when I click on 'Sue Potato' - it is selected and when I refresh the page, it must look the same (be also selected).
I've tried reading some Stateful, Provider, Manager on the Sencha Docs, but I didn't get it.
Controller code:
Ext.define('FirstApp.controller.Main', {
extend: 'Ext.app.Controller',
refs: [
{
ref: 'grid',
selector: 'lesson-grid'
},
{
ref: 'tree',
selector: 'school-tree'
}
],
init: function() {
Ext.state.Manager.setProvider(Ext.create('Ext.state.LocalStorageProvider'));
}
});
Tree code:
Ext.define('FirstApp.view.SchoolTree', {
extend: 'Ext.tree.Panel',
xtype: 'school-tree',
stateful: true,
stateId: 'stateGrid',
stateEvents:['selection'],
constructor: function() {
var that = this;
this.store = Ext.create('FirstApp.store.School');
this.store.on('load', function () {
that.getSelectionModel().select(1, true);
});
this.callParent(arguments);
this.getState = function() {
return that.getSelectionModel().getSelection();
};
this.applyState = function() {
};
}
});
Help would be much appreciated.
This is a working code of the requirement above.I had to get an id of the selected element and then pass it to applyState.
Ext.define('FirstApp.view.SchoolTree', {
extend: 'Ext.tree.Panel',
xtype: 'school-tree',
stateful: true,
stateId: 'stateTree',
stateEvents:['selectionchange'],
constructor: function() {
var that = this;
this.store = Ext.create('FirstApp.store.School');
this.store.on('load', function () {
that.getSelectionModel().select(1);
});
this.callParent(arguments);
},
getState: function() {
return {
'stateTree': this.getSelectionModel().getSelection()[0].getId()
};
},
applyState: function(state) {
var me = this;
this.store.on('load', function(record) {
record = this.getById(state.stateTree);
me.getSelectionModel().select(record);
});
}
});
You stored tree state and set it into State Manager
Ext.state.Manager.setProvider(Ext.create('Ext.state.LocalStorageProvider'));
So when you will refresh your page state will apply and an item will be also selected.
Is there any requirement to store state of tree? If yes and still you don't want to selected then you can forcefully clear selection on tree render.
Hello again everyone.
EDIT: I want to emphasize that I can find no docs on the solution for this.
I am using a route to perform a search query to my server. The server does all the data logic and such and returns a list of objects that match the keywords given. I am taking those results and feeding them to the model so that I can use the {{#each}} helper to iterate over each result.
The problem I am having is that the model does not want to refresh when the searchText (search input) changes. I've tried several things. I'm not worried about creating too many ajax requests as my server performs the search query in 2ms. Here's what I have now.
App.SearchView = Ember.View.extend({...
EDIT:
Thank you for the answer.
App.SearchView = Ember.View.extend({
didInsertElement: function () {
this._super();
Ember.run.scheduleOnce('afterRender', this, this.focusSearch);
},
focusSearch: function () {
$(".searchInput").focus().val(this.get("controller").get('searchTextI'));
}
});
App.SearchRoute = Ember.Route.extend({
model: function () {
return this.controllerFor('search').processSearch();
}
});
App.SearchController = Ember.ArrayController.extend({
searchTextI: null,
timeoutid: null,
processid: null,
updateSearch: function () {
if(this.get('timeoutid')) {clearTimeout(this.get('timeoutid')); }
var i = this.get('searchTextI');
var sc = this;
clearTimeout(this.get('processid'));
this.controllerFor('index').set('searchText', i); //set the search text on transition
if(i.length < 3) {
this.set('timeoutid', setTimeout(function () {
sc.controllerFor('index').set("transitioningFromSearch", true);
sc.transitionToRoute('index');
}, 1500));
} else {
var self = this;
this.set('processid', setTimeout(function() {
self.processSearch().then(function(result) {
self.set('content', result);
});
}, 1000));
}
}.observes('searchTextI'),
processSearch: function () {
return $.getJSON('http://api.*********/search', { 'token': guestToken, 'search_query': this.get('searchTextI') }).then(function(data) { if(data == "No Results Found.") { return []; } else { return data; } }).fail(function() { return ["ERROR."]; });
}
});
Don't observe anything within a route and don't define any computed properties. Routes are not the place for these. Apart from that, the model doesn't fire because controller is undefined.
One way to achieve what you want:
App.SearchRoute = Ember.Route.extend({
model: function () {
this.controllerFor('search').searchQuery();
}.observes('controller.searchText') //not triggering an ajax request...
});
App.SearchController = Ember.ArrayController.extend({
searchQuery: function() {
return $.getJSON('http://api.**************/search', { 'token': guestToken, 'search_query': t }).fail(function() {
return null; //prevent error substate.
});
}
onSearchTextChange: function() {
var controller = this;
this.searchQuery().then(function(result) {
controller.set('content', result);
});
}.observes('searchText')
});
Putting an observes on the model hook is not going to do anything. You should simply do what you were thinking of doing and say
processSearch: function () {
this.set('content', $.getJSON....);
}
I've a controller that uses a Dialog from angular-ui/bootstrap:
function ClientFeatureController($dialog, $scope, ClientFeature, Country, FeatureService) {
//Get list of client features for selected client (that is set in ClientController)
$scope.clientFeatures = ClientFeature.query({clientId: $scope.selected.client.id}, function () {
console.log('getting clientfeatures for clientid: ' + $scope.selected.client.id);
console.log($scope.clientFeatures);
});
//Selected ClientFeature
$scope.selectedClientFeature = {};
/**
* Edit selected clientFeature.
* #param clientFeature
*/
$scope.editClientFeature = function (clientFeature) {
//set selectedClientFeature for data binding
$scope.selectedClientFeature = clientFeature;
var dialogOpts = {
templateUrl: 'partials/clients/dialogs/clientfeature-edit.html',
controller: 'EditClientFeatureController',
resolve: {selectedClientFeature: function () {
return clientFeature;
} }
};
//open dialog box
$dialog.dialog(dialogOpts).open().then(function (result) {
if (result) {
$scope.selectedClientFeature = result;
$scope.selectedClientFeature.$save({clientId: $scope.selectedClientFeature.client.id}, function (data, headers) {
console.log('saved.');
}, null);
}
});
};
});
I'm almost completely new to testing, and figured that maybe I need to test two things:
That a dialog opens when $scope.editClientFeature() is called
That $save is called successfully after a dialog is closed and returns a 'result'
My really messed up test now looks like this:
describe('ClientFeatureController', function () {
var scope, $dialog, provider;
beforeEach(function () {
inject(function ($controller, $httpBackend, $rootScope, _$dialog_) {
scope = $rootScope;
$dialog = _$dialog_;
//mock client
scope.selected = {};
scope.selected.client = {
id: 23805
};
$httpBackend.whenGET('http://localhost:3001/client/' + scope.selected.client.id + '/clientfeatures').respond(mockClientFeatures);
$controller('ClientFeatureController', {$scope: scope});
$httpBackend.flush();
});
});
it('should inject dialog service from angular-ui-bootstrap module', function () {
expect($dialog).toBeDefined();
console.log($dialog); //{}
});
var dialog;
var createDialog = function (opts) {
dialog = $dialog.dialog(opts);
};
describe('when editing a clientfeature', function () {
createDialog({});
console.log(dialog); //undefined
// var res;
// var d;
// beforeEach(function () {
// var dialogOpts = {
// template: '<div>dummy template</div>'
// };
// console.log(dialog);
// d = $dialog.dialog(dialogOpts);
// d.open();
// });
//
// it('should open a dialog when editing a client feature', function () {
// expect(d.isOpen()).toBe(true);
// });
});
});
The immediate problem now is that I'm unable to create/open a dialog. I get the following error:
Chrome 25.0 (Mac) ClientFeatureController when editing a clientfeature encountered a declaration exception FAILED
TypeError: Cannot call method 'dialog' of undefined
It would be great if someone has already written a test for a similar use case and can provide me with an example as I'm pretty lost.
Thanks,
Shaun
I was struggling with the same problem until right now, after trolling the the github repo i found the dialog tests and used that as a starting point :
var $dialog,$scope,$httpBackend;
beforeEach(module('ui.bootstrap.dialog'));
beforeEach(function(){
inject(function (_$dialog_, _$httpBackend_, $controller){
$dialog = _$dialog_;
$httpBackend = _$httpBackend_;
$httpBackend.expectGET('/appServer/list')
.respond([{
id:1,
name:'test1'
},
{
id:2,
name:'test2'
},
{
id:3,
name:'test3'
}]);
//setup controller scope
scope = {};
ServerCtrl = $controller('ServerCtrl', {
$scope: scope,
$dialog:$dialog
});
});
});
I also prefer a proper mock. When it is not available, i patch the service
To test this:
$dialog.messageBox(title, msg, btns)
.open()
.then(function (result) {
if (result == 'ok') {
// block executed if user click OK
}
});
You can patch $dialog like this:
$dialog.messageBox = function (title, msg, btns) {
return {
open: function () {
return {
then: function (callback) {
callback('ok'); // 'ok' will be set to param result
}
}
}
}
};
Personally I try to mock all services out. If the ui-bootstrap project does not provide a $dialog mock, you should open a bug ticket there and ask them for one. However creating one is as easy.
The mock service should have fake methods that do nothing but return promises. It should also give you a method to flush all asynchronous methods to make it easier to do synchronous testing.
I find it clearest to write my own mock of the dialog. Here's an example of mocking out a dialog to simulate "yes" being chosen.
Code under test
.controller('AdminListingCtrl', function AdminListingController($scope, $dialog, houseRepository) {
$scope.houses = houseRepository.query();
$scope.remove = function (house) {
var dlg = $dialog.messageBox('Delete house', 'Are you sure?', [
{label: 'Yep', result: 'yes'},
{label: 'Nope', result: 'no'}
]);
dlg.open().then(function (result) {
if (result == 'yes') {
houseRepository.remove(house.id);
$scope.houses = houseRepository.query();
}
});
};
}
Tests
describe('when deleting a house', function () {
var fakeDialog = {
open: function()
{
return {
then: function(callback) {
callback("yes");
}
};
}
};
beforeEach(inject(function($dialog) {
spyOn($dialog, 'messageBox').andReturn(fakeDialog);
}));
it('should call the remove method on the houseRepository', function () {
scope.remove({id: 99});
expect(houseRepository.remove).toHaveBeenCalledWith(99);
});
// etc
});