I am newbie to Sencha. Can anyone please explain how to support back button in android using Sencha touch2 Routing. I have gone through Sencha document, they explained there with senarios like "#products/123". But in my case only views get changed not url which is always like "../index.html".
Lets consider i have one login page. On login button tap it navigates to Home page. Now on device back button tap it should navigate back to login. So what format should i put inside route:{}.
Please anyone explain me with simple code.
Thanks in advance.
in your button actions you should redirect like this:
control: {
'button[action=login]' : {
tap: function() {
this.redirectTo('login');
}
}
Then add the route in your controller:
config: {
refs: {
main: 'main'
},
routes: {
'login': 'showLogin'
}
}
and finally in the showDetail function you make the view change, the url should show something like index.html#detail:
showLogin: function() {
this.getMain().push({
xtype: 'loginView'
});
}
I hope this helps!
After doing lot of Google search finally got the answer with proper example. So this is for reference http://thanksmister.com/?p_=336
You can also give yourself better control by defining the Back Button, as well as its references, instead of using the default.
Ext.define('Mov.view.BackButton', {
extend: 'Ext.Button',
alias: 'widget.backbutton',
config: {
hidden: true,
id: 'back',
ui: 'back',
text: 'Back',
backStack: {
}
},
addToBackStack: function(dispatchOptions) {
var found = false;
this.backStack.forEach(function(el) {
found = found || (Ext.encode(el) == Ext.encode(dispatchOptions));
});
if (!found) {
this.backStack.push(dispatchOptions);
}
this.show();
},
clearBackStack: function() {
this.backStack = [];
this.hide();
},
handler: function(button, event) {
var dispatchOptions = this.backStack.pop();
Ext.dispatch(dispatchOptions);
if(this.backStack.length === 0) {
this.hide();
}
}
});
Then on your app's navigation bar, you apply this widget. (onInitialize of initial view works well).
nav = this.getNavigationBar(),
nav.setBackButton(Ext.widget('backbutton'));
#jurodr has a nice example for routing, reference and control, which works well with this custom component.
Related
I´m new on Angular and try to parse Adobe IDML (XML) files for showing them up in a browser. Let me explain that:
There is the following XML-Structure ("->" means gives info about next line):
IDML (designmap.xml) ->
Spread (spread_xy.xml) ->
Page ->
TextFrames ->
Story
Rectangle ->
Image
I have written a backend that translates these files in JSON-Arrays and I load these JSON-Arrays via HTTP. So far so good.
The following is my corresponding IDML-Service in the Frontend:
export class IdmlService {
apiUrl = environment.backendApi + 'idml/';
constructor(private http: HttpClient) { }
renderSpread(currentFolder, currentSpreadId): Observable<HttpResponse<any[]>> {
return this.http.get<MenuItem[]>(
this.apiUrl + currentFolder + '?spreadId=' + currentSpreadId, { observe: 'response' }).pipe(
retry(3)
);
}
}
I call "renderSpread"-method in my publicationComponent like this:
renderPublication(currentFolder: String, currentSpreadId: String): void {
this.idmlService.renderSpread(currentFolder, currentSpreadId)
.subscribe(resp => {
this.currentSpreadJson = resp.body;
// console.log(this.currentSpreadJson);
});
}
and bind the "currentSpreadJson" to the child component called spreadComponent in the template:
<div class="publication">
<app-spread [currentSpreadJson]="currentSpreadJson"></app-spread>
</div>
In the spreadComponent I construct my currentSpread and bind the necessary rest of JSON via "currentElementsJson" to the next child elementsComponent like this:
#Input() currentSpreadJson: any;
currentSpread: Spread;
currentElementsJson: any;
ngOnInit() {
setTimeout(() => { // THE MAIN PROBLEM
this.render();
}, 3000);
}
render(): void {
this.currentSpread = {
id: this.currentSpreadJson.idPkg_Spread.Spread['Self'],
[...some other vars...]
};
[...doing some stuff...]
this.currentElementsJson = this.currentSpreadJson.idPkg_Spread.Spread;
}
Here´s the template:
<div id="{{currentSpread.id}}" class="spread box_shadow" [ngStyle]="{'width': currentSpread.width + 'px', 'height': currentSpread.height + 'px'}">
<app-page [currentSpreadJson]="currentSpreadJson"></app-page>
<app-element [currentElementsJson]="currentElementsJson"></app-element> // <-- here
</div>
So here my question: Such an IDML could become very huge. This strategy goes deeper in the XML-Tree and the problem is that I always need to do a timeout onInit. I tried some other lifecycles like ngAfterViewInit and so on, but I think the upper strategy is not the thing I need for my project. I heared about "async await"-functions, but I don´t really know how to implement that in this context and I´m not sure if this is the solution. It would be nice if somebody could give me a hint. Thank you.
Regards, Dominik
This worked for me now. I changed this:
ngOnInit() {
setTimeout(() => { // THE MAIN PROBLEM
this.render();
}, 3000);
}
to that:
ngAfterContentChecked() {
this.render();
}
Now the nested components wait until the Content is available.
Regards
I have a DataTable and I am loading it using Angular Js, I have Created a directive and wrapped my DataTable in this directive, A common approach of wraping JQuery Plugin in Directive so that it can live in Angular Digest Cycle.
But the ng-click that is on button and coming from render Function of column in datatable is not clickable (Not Working, Angular did not compiled it). Is there any way to make it Clickable. I know the approach in which we use {{}} with ng-repeatto populate data in datatable. I'm looking a directive way, so you can tell me what is stoping ng-click from working or how to make my directive right! Please stick with directive approach. Code is following.
App.directive('jqtable', function () {
return {
restrict: 'E, A, C',
link: function (scope, element, attrs, controller) {
var dataTable = element.dataTable(scope.options);
scope.$watch('options.data', handleModelUpdates, true);
function handleModelUpdates(newData) {
var data = newData || null;
if (data) {
dataTable.fnClearTable();
dataTable.fnAddData(data);
}
}
},
scope: {
options: "="
}
};
});
And here is my Controller:-
$scope.options = {
aoColumnDefs: [{
"bSortable": true,
"aTargets": [ 1],
"render": function ( data, type, full, meta ) {
if(meta.col==1){
return data+" <a class='btn btn-sm btn-default' ng-click='showalert()' >Click me </a>"
}
}
}],
bJQueryUI: true,
bDestroy: true,
data:$scope.data
};
$scope.showalert=()=>
{
alert("Angular Compiled the Html");
}
Angular does not know you have injected elements to the DOM. You must $compile each row. You can do that in rowCallback. Since DataTables may inject new rows when the table is filtered, sorted or upon page change, you can add a compiled flag to prevent rows from being $compiled multiple times :
$scope.options = {
rowCallback: function(row) {
if (!row.compiled) {
$compile(angular.element(row))($scope);
row.compiled = true;
}
}
...
}
see http://next.plnkr.co/edit/KxwqSVXIogtXYx4I
am new in creating chrome extensions, I'm developing an extension page action it works in certain urls, I would like to put different text in the popup for each url, i can do it? please help me.
My background.js is thus
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (~tab.url.indexOf('url1.com.br')) {
chrome.pageAction.show(tabId);
}
if (~tab.url.indexOf('url2.com.br')) {
chrome.pageAction.show(tabId);
}
});
OK. First of all, to show page_action icon on specific URLs you can use declarative content.
// When the extension is installed or upgraded ...
chrome.runtime.onInstalled.addListener(function() {
// Replace all rules ...
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
// With a new rule ...
chrome.declarativeContent.onPageChanged.addRules([
{
// That fires when a page's on a specific URL
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { urlContains: 'url1.com.br' },
}),
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { urlContains: 'url2.com.br' }
})
],
// And shows the extension's page action.
actions: [ new chrome.declarativeContent.ShowPageAction() ]
}
]);
});
});
Don't forget adding a permission for declarative content in manifest.json. Another thing is different texts for different urls.
popup.js
chrome.tabs.query({'active': true, 'currentWindow': true}, function (tabs) {
var dynamicText = "You are here;"+ tabs[0].url;
document.getElementById("textbox").value = dynamicText ;
});
This sample gets the currentWindow's URL and insert it into the element that has textbox id. I hope samples are enough to solve the problem.
I am unable to view the HTML content of web pages when I view source in Google Chrome's dev tools. For example, if I view the source of https://stackoverflow.com/help, the only content I can see is as follows.
<script>
$('#herobox li').click(function () {
StackExchange.using("gps", function () {
StackExchange.gps.track("aboutpage.click", { aboutclick_location: "hero" }, true);
});
window.location.href = '/about';
});
$('#tell-me-more').click(function () {
StackExchange.using("gps", function () {
StackExchange.gps.track("aboutpage.click", { aboutclick_location: "hero" }, true);
});
});
$('#herobox #close').click(function () {
StackExchange.using("gps", function () {
StackExchange.gps.track("hero.action", { hero_action_type: "minimize" }, true);
});
$.cookie("hero", "mini", { path: "/" });
$.ajax({
url: "/hero-mini",
success: function (data) {
$("#herobox").fadeOut("fast", function () {
$("#herobox").replaceWith(data);
$("#herobox-mini").fadeIn("fast");
});
}
});
return false;
});
</script>
I'm not sure if I've inadvertently changed a setting in Chrome, but any help would be greatly appreciated.
I'm using chrome Version 29.0.1547.76.
I have disabled all extensions.
I tried this using a new profile with the same effect.
I'm not behind a proxy.
If you open the DevTools after loading the page, the content of the items listed on the Resources tab may not be populated. This is also true of network requests on the Network tab. To see the fully populated resources on the Resources tab, first open the DevTools, then refresh the page, or navigate to the desired page with the DevTools open. Now select the html resource and it should be populated.
I have just started working with Backbone.js by creating a simple portfolio site for myself. There is not much functionality at the moment but I hope to add more & more as I become familiar with the library. I am using json to populate the data for the site which either lists all my portfolio items or displays one of them depending on the route. I have the list of portfolio items working/showing but am struggling to just show one item for a specific route (/#projects/2 for example), this is where I need help.
I have tried to keep everything as simple as possible while I start learning Backbone & have seen the various Boilerplates & tutorials, none of which helped me hugely.
At these routes, I would like this to happen:
/ - list of portfolio items
/#projects - list of portfolio items
/#projects/3 - one portfolio item
I have put my attempt into JSbin but it is not working because I don't know how to load the json properly...
http://jsbin.com/asezul/6/edit to edit
http://jsbin.com/asezul/6/ to view
I am certain my problem arises because I am loading all items into the collection rather than the model. Is that right?
How can I make this work?
How can I improve this?
[EDIT --------------------]
After Peter's very kind help below, I am still in need of assistance. He said:
A view displays 1 model, a collection view displays a list of views,
one per model.
So, how do I create a View to display one item from the json data & then create the collection view to display all of them? The reason I ask is because I can return all them without much of a problem but returning a single item is proving quite tricky..
I updated my code example too: http://jsbin.com/asezul/8/edit
[---------------------EDIT]
Please let me know if you need more information, I am new to Backbone & may have missed an important part that would help to answer my questions.
Here's some code excerpts but I suggest viewing the code in JSbin:
The model:
SITE.Project = Backbone.Model.extend({
initialize: function() {
console.log(this, this.attributes.name);
}
});
The collection:
SITE.Projects = Backbone.Collection.extend({
model: SITE.Project,
url: 'content.json',
parse: function(response) {
console.log(response);
return response.portfolio;
}
});
A view:
SITE.ProjectsView = Backbone.View.extend({
el: '#main',
initialize: function() {
_.bindAll(this, 'render');
// create a collection
this.collection = new SITE.Projects();
// Fetch the collection and call render() method
var that = this;
this.collection.fetch({
success: function () {
that.render();
}
});
},
template: SITE.helpers.template('project-list'),
render: function() {
$(this.el).html(this.template({ projects: this.collection.toJSON() }));
}
});
The router:
SITE.Router = Backbone.Router.extend({
initialize: function() {
this.el = $('#main');
},
routes: {
"": "index",
"projects": "projects",
"projects/:id": "project"
},
// Homepage / List of projects
index: function() {
var view = new SITE.ProjectsView();
},
// List of projects
projects: function() {
var view = new SITE.ProjectsView();
},
// Individual Project
project: function(id) {
var view = new SITE.ProjectView();
console.log("You are trying to reach project " + id);
}
});
So your data isn't really dynamic, so you can cheat a little bit compared to a dynamic application where the projects collection would be under constant change. I would just load the projects collection once at app startup and from there use the loaded collection and models within for the rest of your pages.
SITE.Router = Backbone.Router.extend({
initialize: function() {
//Router's don't have a this.el
//this.el = $('#main');
this.projects = new SITE.Projects();
},
routes: {
"": "index",
"projects": "projects",
"projects/:id": "project"
},
// Homepage / List of projects
index: function() {
var view = new SITE.ProjectsView({collection: this.projects});
if (this.projects.isEmpty()) {
this.projects.fetch({success: function () {
view.render();
}});
} else {
view.render();
}
},
// List of projects
projects: function() {
var view = new SITE.ProjectsView({collection: this.projects}).render();
},
// Individual Project
project: function(id) {
var view = new SITE.ProjectView({model: this.projects.get(id)}).render();
}
});
Then keep your views simpler/dumber. Views should accept their models/collections in the options argument of the constructor/initialize. Give that a try and see if you can make it work. Your code otherwise looks like you should be able to make the corresponding view code changes on your own, so I'll leave that as an exercise for the reader.