ASP.Net Boilerplate & jTable - asp.net

I have studied the ASP.Net boilderplate template (http://www.aspnetboilerplate.com/Templates) and made some custom changes.
I have a "GetComponentDataList()" method in my services. I played around with that and rendered it as a list like shown here:
<!-- Component list -->
<ul class="list-group" ng-repeat="component in vm.components">
<div class="list-group-item">
<br />
<span>Entry:</span>
<span>{{component.entry}}</span>
</div>
</ul>
components.js code:
vm.refreshComponents = function () {
abp.ui.setBusy( //Set whole page busy until getComponentDataList complete
null,
componentDataService.getComponentDataList( //Call application service method directly from javascript
).success(function (data) {
vm.components = data.componentData;
})
);
};
Now I would like to render the components via jTable. jTable expects an action to get the list of data:
listAction: '/api/services/app/componentData/GetComponentDataList',
How do I use jTable from boilerplate template?
1. Do I need to add a method in my "HomeController" to use jTable?
2. The result of my "GetComponentDataList" method in my service is of type IOutputDto.
That means the result of my service is not directly a list. There is one indirection
level inbetween. Seems like this does not fit together.
3. Can I provide a function in my JS-ViewModel and use that function instead of an action URL?
Any hint would be awesome.
Thx.

I'm working on a sample project to work ABP with jTable. I did not finish it yet. But you can check it. https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/AbpWithjTable
Add abp.jtable.js to your file (https://github.com/aspnetboilerplate/aspnetboilerplate-samples/blob/master/AbpWithjTable/AbpjTable.Web/App/Main/libs/abp.jtable.js) after all ABP and jtable scripts.
See example js: https://github.com/aspnetboilerplate/aspnetboilerplate-samples/blob/master/AbpWithjTable/AbpjTable.Web/App/Main/views/people/people.js
See example C# App service: https://github.com/aspnetboilerplate/aspnetboilerplate-samples/blob/master/AbpWithjTable/AbpjTable.Application/People/PersonAppService.cs

Related

SvelteKit: Pass Data From +Layout.svelte To +page.svelte SPA (static) application

I'm struggling with the latest version of SvelteKit, the docs available only works with SSR, and I'm developing SPA app (static page), so, what is the way to pass data from my +layout.svelte to +page.svelte?.
The documentation says that with load function from page.js (I've already set the SSR=false, and I understood that page.js is for SSR), but that doesn't work with SPA, and if I have the load function from the layout it's seems not work.
Aditionaly I want to trigger a function from my +page.svelte that is in the layout page.
Any ideas?
here my try
//+layout.svelte
<script>
export function load() {
return {
data: { title: 'default title' }
};
}
export let data;
</script>
//+page.svelte
<script>
export let data;
console.log(data.title); //undefined
</script>
the docs says that don't use: <script context="module">, and I don't want to use the store becouse I think that sholud be a better way.
Load functions belong in the accompanying files +layout.js/ts, not on the page. They also do not return a property data, everything returned is the data. See the docs.
If SSR is disabled, you can event return a store that could be modified from the page.
To get a store from the data so it can be used with $-syntax, the data property can be destructured on the page:
export let data;
$: ({ title } = data);
You could also create a store and set it as a context in the layout. Pages then can get said context and interact with it. This allows two-way interaction.
Using a store is necessary if the contents require reactivity (i.e. are changed) and the page or layout needs to update.

How to provide initial data for client side javascript?

I just wonder if there was a new way to provide an initial data (json) for client side processing? I'm using ASP.NET Core MVC and I try to avoid an initial ajax request for data.
Currently I can render the Model into a json data within my asp.net view:
<script>
var serverData = #Json.Serialize(Model); //List<TextItem>
</script>
Then I can access that serverData in my client script (VueJs, .vue component file):
<template>
<ul>
<li v-for="item in list">{{item.text}}</li>
</ul>
</template>
<script>
export default {
data: function () {
return {
list: serverData
}
}
};
</script>
Solution works fine but I don't really like to render raw data into the page source. Is there any more elegant way to provide an inital data without any additinal (ajax) request to the server?
Edit:
I found an article about the concept (it uses angular):
https://blog.mariusschulz.com/2014/03/25/bootstrapping-angularjs-applications-with-server-side-data-from-aspnet-mvc
Is it still the best way to pre-render data on server side?

how to attach events to generated html of a template in Meteor 0.8 with Blaze

I'm using Meteor 0.8 with Blaze and I want to attach events dynamically to HTML contents generated using UI.toHTML of a template. The functionality I am looking for is the alternative to Spark.attachEvents in Blaze.
What I have done so far is that I have created the following template to be used like a widget/component.
<template name="postLinks">
<div id="link-popover-wrapper" >
<ul class="link-popover">
{{#each linkOptions}}
<li><a tabindex="-1" class="link-action" id="link-{{value}}" href="#">{{label}}</a>
</li>
{{/each}}
</ul>
</div>
</template>
And the template is used in Helper of the myPostItem template.
Template.myPostItem.events({
'click .post-item-link-picker': function (evt, tmpl) {
var tempData = {linkOptions:[{label:'Favorite', value : 'favorite'}, ...]};
// Get the HTML content of the template passing data
var linkContent = UI.toHTML(Template['postLinks'].extend({data: function () { return tempData; }}));
// Attach events to the linkContent like in Spark
/*Spark.attachEvents({
'click link-action': function (e, tmpl) {
alert("Component item click");
}
}, linkContent);*/
// Popover the content using Bootstrap popover function
}
});
So my requirement is to attach events to a dynamically generated HTML contents.in the linkContent like Spark.attachEvents after the following line as mentioned in above code.
var linkContent = UI.toHTML(Template['postLinks'].extend({data: function () { return tempData; }}));
Hope somebody can help to find a way to do this in Meteor 0.8 with Blaze.
The reason that Spark-generated HTML could be directly inserted into the DOM is because it had "landmarks" - annotations that could be processed into events and handlers when the DOM nodes were materialized.
Blaze works differently - it inserts a UI component into the DOM directly and attaches events, using the UI.render function. It cannot directly attach template events to the DOM if you use UI.toHTML because there are none of the annotations that Spark had for doing this.
I'm also using Bootstrap popovers in my app, and as far as I know there's no clean way to insert reactive content into a popover. However, you can approximate it with a hack in the following way:
In the content callback of the popover, render the template with UI.toHTML - a nonreactive version of the content. This is necessary because otherwise the popover won't be sized and positioned properly.
Using a Meteor.defer call, replace the popover contents with reactive content, so they'll continue updating while the popover is open.
Because Bootstrap uses jQuery, you should be fine with removing reactive logic properly, for now. Future versions of Meteor will probably have easier ways to do this.

Trigger.io + Angular.js and updating a view after calling forge.ajax

Having a problem, and so far couldn't get any solutions for seemingly similar SO questions to work. Problem is this:
Using Trigger.io's forge.ajax, my Angular.js view is not updated after the data is returned. I realize this is because forge.ajax is an asychronous function, and the data is returned after the view has already been displayed. I have tried to update the view by using $rootScope.apply(), but it doesn't work for me as shown in the many examples I have seen.
See the Controller code below:
function OfferListCtrl($scope) {
$scope.offers = [];
$scope.fetchOffers = function(callback) {
$scope.offers = [];
var successCallback = function(odataResults) {
var rawJsonData = JSON.parse(odataResults);
var offers = rawJsonData.d;
callback(offers);
};
var errorCallback = function (error){
alert("Failure:" + error.message);
};
forge.request.ajax({
type: 'GET',
url: 'https://www.example.com/ApplicationData.svc/Offers',
accepts: 'application/json;odata=verbose',
username: 'username',
password: 'password',
success: successCallback,
error: errorCallback
});
};
$scope.fetchOffers(function(offers) {
$scope.offers = offers;
forge.logging.info($scope.offers);
});
}
All the code there works fine, and $scope.offers gets populated with the Offer data from the database. The logging function shows the data is correct, and in the correct format.
I have tried using $rootScope.apply() in the logical places (and some illogical ones), but cannot get the view to update. If you have any ideas how I can get this to work, I would greatly appreciate it.
Edit: Added HTML
The HTML is below. Note the button with ng-click="refresh()". This is a just a workaround so I can at least see the data. It calls a one-line refresh function that executes $rootScope.apply(), which does update the view.
<div ng-controller="OfferListCtrl">
<h1>Offers</h1>
<ul>
<li ng-repeat="offer in offers">
<p>Description: {{offer.Description}}<br />
Id: {{offer.Id}}<br />
Created On: {{offer.CreatedOn}}<br />
Published: {{offer.Published}}<br />
</p>
</li>
</ul>
<input type="button" ng-click="refresh()" value="Refresh to show data" />
</div>
You need to change
$scope.fetchOffers(function(offers) {
$scope.$apply(function(){
$scope.offers = offers;
});
forge.logging.info($scope.offers);
});
It is because all changes to the $scope has to be made within the angular scope, in this case since you are calling ajax request using forge the callback is not executing within the angular framework, that is why it is not working.
You can use $scope.$apply() in this case to execute the code within angular framework.
Look at the $apply() methods doc
$apply() is used to execute an expression in angular from outside of
the angular framework. (For example from browser DOM events,
setTimeout, XHR or third party libraries). Because we are calling into
the angular framework we need to perform proper scope life-cycle of
exception handling, executing watches.
do this
function MyController($scope, myService)
{
myService.fetchOffers(data){
//assign your data here something like below or whateever
$offers = data
$scope.$apply();
}
});
Thanks
Dhiraj
When I do that I have an error like : "$digest already in progress"...
I'm Working with $q...
Someone knwo how I can resolve this issue ?
yes, this is caused where ur data comes fast enough and angular has not finished his rendering so the update cant update "outside" angular yet.
so use events:
http://bresleveloper.blogspot.co.il/2013/08/angularjs-and-ajax-angular-is-not.html

Using a custom javascript script file with durandal template

I work on a Visual Studio 2012 MVC4 Project with the Durandal template. In this template, the shell.js page gives us a quite simple menu solution where every elements are located on top. Personally I need something different. For that purpose, I have a javascript file named dropdown.js which allows me to show/hide sub menus. It works pretty well in a standard project but I was not able to do it working with the durandal template.
Here is what I try:
I added a reference to the dropdown.js script in the Index.chtml:
<script src="~/Scripts/dropdown.js"></script>
Then in the shell.html page, I would like to use it like this:
<li class="dropdown" data-role="dropdown">
...
...
</li>
Here is a little portion of the dropdown.js:
$(function () {
alert('XXXX');
$('[data-role="dropdown"]').each(function () {
alert('YYYY');
$(this).Dropdown();
})
})
As you can see, each element decorated with the 'dropdown' class should have been catched. It doesn't work with durandal. I placed some alert boxes to check it. The alert 'XX' is showed but the alert 'YY' is never showed.
I searched a bunch of hours without success.
Any idea?
Check out the life cycle events tha tyou can tap into for Durandal here
viewAttached may help since you can tap into when the view and dom are ready.
I think the problem is that when the dropdown.js function is executed before the menu renders and because of that the jquery selector doesn't catch any list item.
I think that your best option is to make a knockout binding to transform your list items in dropdowns.
The binding would look something like:
ko.bindingHandlers.dropdown= {
init: function (element, valueAccessor, allBindingsAccessor) {
$(element).Dropdown();
},
update: function (element, valueAccessor) {
}
};
And in the view:
<li class="dropdown" data-bind="dropdown : {}">
...
...
</li>

Resources