I have a Recipe project and I want to delete those recipes through a button. I have 3 components:
RecipesCar: Who prints the recipes
RecipesList: Who load de list
App: Who has the recipes object.
I'm trying to delete the recipes but at this moment is not working. I can capture the events but is not working cause the recipes are not deleting.
Here my code:
RecipesCard:
<template>
<div class="recipe" :class="recipe.featured && 'featured'">
<button class="delete-recipe">
<img
src="../assets/delete-button.svg"
alt="Delete recipe"
#click="deleteRecipe(this.recipe.id)"
/>
</button>
<h2 class="recipe-title">{{ recipe.title }}</h2>
<div class="recipe-image">
<img :src="recipe.imageUrl" />
</div>
<div class="recipe-info">
<div class="recipe-info-item">
<span class="recipe-info-label">Servings:</span>
<span class="recipe-info-value">{{ recipe.servings }}</span>
</div>
<div class="recipe-info-item">
<span class="recipe-info-label">Time:</span>
<span class="recipe-info-value">{{ recipe.time }}</span>
</div>
<div class="recipe-info-item">
<span class="recipe-info-label">Difficulty:</span>
<span class="recipe-info-value">{{ recipe.difficulty }}</span>
</div>
</div>
<div class="recipe-ingredients">
<h3 class="recipe-ingredients-title">Ingredients</h3>
<ul class="recipe-ingredients-list">
<li v-for="ingredient in recipe.ingredients" :key="ingredient">
{{ ingredient }}
</li>
</ul>
</div>
<div class="recipe-directions">
<h3 class="recipe-directions-title">Directions</h3>
<ol class="recipe-directions-list">
<li v-for="direction in recipe.directions" :key="direction">
{{ direction }}
</li>
</ol>
</div>
</div>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
name: "RecipeCard",
props: {
recipe: {
type: Object,
required: true,
},
},
methods: {
deleteRecipe() {
console.log(this.recipe.id);
this.$emit("my-event-delete", this.recipe.id);
},
},
});
</script>
RecipesList:
<template>
<div id="recipe-list" class="recipe-list">
<div v-for="(recipe, id) in recipeList" :key="recipe.id">
<recipe :recipe="recipe" #my-event-delete="deleteRecipe(id)" />
</div>
</div>
</template>
<script>
import { defineComponent } from "vue";
import Recipe from "./RecipeCard.vue";
export default defineComponent({
name: "RecipeList",
props: {
recipeList: {
type: Array,
required: true,
},
},
components: { Recipe },
methods: {
deleteRecipe(id) {
console.log("Componente borrado " + id);
},
},
});
</script>
App
<template>
<div id="app">
<div class="header">
<img class="logo" alt="UOC logo" src="./assets/uoc-logo.png" />
<div class="app-name">Recipe book</div>
</div>
<search-bar />
<recipe-list :recipeList="recipeList" #deleteRecipe="deleteRecipe" />
<recipe-form v-if="showModal" />
</div>
</template>
<script>
import RecipeList from "./components/RecipeList.vue";
import RecipeForm from "./components/RecipeForm.vue";
import SearchBar from "./components/SearchBar.vue";
import { defineComponent } from "vue";
export default defineComponent({
name: "App",
components: {
RecipeList: RecipeList,
RecipeForm,
SearchBar,
},
data: () => ({
recipeList: [
{
id: 1,
servings: 4,
time: "30m",
difficulty: "Easy",
title: "Spaghetti",
ingredients: ["noodles", "tomato sauce", "cheese"],
directions: ["boil noodles", "cook noodles", "eat noodles"],
imageUrl:
"https://imagesvc.meredithcorp.io/v3/mm/image?q=60&c=sc&poi=face&w=2000&h=1000&url=https%3A%2F%2Fstatic.onecms.io%2Fwp-content%2Fuploads%2Fsites%2F21%2F2018%2F02%2F14%2Frecetas-4115-spaghetti-boloesa-facil-2000.jpg",
},
{
id: 2,
servings: 2,
time: "15m",
difficulty: "Medium",
title: "Pizza",
ingredients: ["dough", "tomato sauce", "cheese"],
directions: ["boil dough", "cook dough", "eat pizza"],
imageUrl:
"https://www.saborusa.com/wp-content/uploads/2019/10/Animate-a-disfrutar-una-deliciosa-pizza-de-salchicha-Foto-destacada.png",
featured: true,
},
{
id: 3,
servings: 6,
time: "1h",
difficulty: "Hard",
title: "Salad",
ingredients: ["lettuce", "tomato", "cheese"],
directions: ["cut lettuce", "cut tomato", "cut cheese"],
imageUrl:
"https://www.unileverfoodsolutions.es/dam/global-ufs/mcos/SPAIN/calcmenu/recipes/ES-recipes/In-Development/american-bbq-beef-salad/main-header.jpg",
},
],
showModal: false,
}),
methods: {
deleteRecipe() {
console.log("this.id");
this.recipeList.splice(this.recipeList.indexOf(this.id), 1);
},
},
});
</script>
Can you help me plz? Thanks
I tried to make and 'emit' but the emit stops on RecipeList.
Related
I was looking through a tutorial located here: https://daily-dev-tips.com/posts/creating-a-sidebar-layout-in-nextjs-with-tailwind/ about a sidebar.
I was wondering if there was a way to use Icons (like heroicons) within the layout file.
referenced below:
import Link from "next/link";
import { useRouter } from "next/router";
import HomeIcon from "#heroicons/react/outline";
export default function Layout({ children }) {
const router = useRouter();
const menuItems = [
{
href: "/",
title: "Home",
},
{
href: "/about",
title: "About",
},
{
href: "/contact",
title: "Contact",
},
];
return (
<div className="min-h-screen flex flex-col">
<header className="bg-white sticky top-0 h-14 flex justify-center items-center font-semibold uppercase">
Next.js sidebar menu
</header>
<div className="flex flex-col md:flex-row flex-1">
<aside className="bg-black w-full md:w-60">
<nav>
<ul>
{menuItems.map(({ href, title }) => (
<li className="m-2" key={title}>
<Link href={href}>
<a
className={`flex p-2 bg-black text-white rounded hover:bg-red-600 cursor-pointer ${
router.asPath === href && "bg-black text-red-600"
}`}
>
{title}
</a>
</Link>
</li>
))}
</ul>
</nav>
</aside>
<main className="flex-1">{children}</main>
</div>
</div>
);
}
I tried
href: "/",
title: "Home",
icon: <HomeIcon />,
but then I wasn't sure exactly how to incorporate it. Any ideas?
First, import as below:
import { ChatIcon, HomeIcon, PhoneIcon } from "#heroicons/react/outline";
Then put the icons in menu items:
const menuItems = [
{
href: "/",
title: "Homepage",
icon: <HomeIcon className="h-4 w-4 mx-2" />,
},
{
href: "/about",
title: "About",
icon: <ChatIcon className="h-4 w-4 mx-2" />,
},
{
href: "/contact",
title: "Contact",
icon: <PhoneIcon className="h-4 w-4 mx-2" />,
},
];
then, update your list by adding icon here {menuItems.map(({ href, title, icon }) and at the achor {icon} {title}
{menuItems.map(({ href, title, icon }) => (
<li className="m-2" key={title}>
<Link href={href}>
<a className={`inline-flex items-center w-full p-2 bg-fuchsia-200 rounded hover:bg-fuchsia-400 cursor-pointer ${router.asPath === href && "bg-fuchsia-600 text-white"}`}
>
{icon} {title}
</a>
</Link>
</li>
))}
and update the Link anchor class flex become inline-flex items-center w-full
Finally, the complete layout.js file is as follows:
import Link from "next/link";
import { useRouter } from "next/router";
import { ChatIcon, HomeIcon, PhoneIcon } from "#heroicons/react/outline";
export default function Layout({ children }) {
const router = useRouter();
const menuItems = [
{
href: "/",
title: "Homepage",
icon: <HomeIcon className="h-4 w-4 mx-2" />,
},
{
href: "/about",
title: "About",
icon: <ChatIcon className="h-4 w-4 mx-2" />,
},
{
href: "/contact",
title: "Contact",
icon: <PhoneIcon className="h-4 w-4 mx-2" />,
},
];
return (
<div className="min-h-screen flex flex-col">
<header className="bg-purple-200 sticky top-0 h-14 flex justify-center items-center font-semibold uppercase">
Next.js sidebar menu
</header>
<div className="flex flex-col md:flex-row flex-1">
<aside className="bg-fuchsia-100 w-full md:w-60">
<nav>
<ul>
{menuItems.map(({ href, title, icon }) => (
<li className="m-2" key={title}>
<Link href={href}>
<a
className={`inline-flex items-center w-full p-2 bg-fuchsia-200 rounded hover:bg-fuchsia-400 cursor-pointer ${
router.asPath === href && "bg-fuchsia-600 text-white"
}`}
>
{icon} {title}
</a>
</Link>
</li>
))}
</ul>
</nav>
</aside>
<main className="flex-1">{children}</main>
</div>
</div>
);
}
i suggest change the array object like this.
sample https://codesandbox.io/s/epic-stitch-h5gn89?file=/src/App.js
{
href: "/",
title: "Home",
icon: "HomeIcon",
}
and use this component i found on this link.(i changed some of it) https://github.com/tailwindlabs/heroicons/issues/278#issuecomment-851594776
in this solution dont need to import eche icon one by one
DynamicHeroIcon.tsx
// DynamicHeroIcon.tsx
// Simple Dynamic HeroIcons Component for React (typescript / tsx)
// by: Mike Summerfeldt (IT-MikeS - https://github.com/IT-MikeS)
import { FC } from "react";
import * as HIcons from "#heroicons/react/outline";
const DynamicHeroIcon: FC<{ icon: string } & React.HTMLProps<HTMLElement>> = (
props
) => {
const { ...icons } = HIcons;
const Fprops = { ...props };
delete Fprops.icon;
// #ts-ignore
const TheIcon: JSX.Element = icons[props.icon];
return (
<>
{/* #ts-ignore */}
<TheIcon {...Fprops} aria-hidden="true" />
</>
);
};
export default DynamicHeroIcon;
and use it like this.
import DynamicHeroIcon from "./components/DynamicHeroIcon";
<DynamicHeroIcon style={{ width: "52px" }} icon={"HomeIcon"} />
{list.map((item) => {
return <DynamicHeroIcon style={{ width: "52px" }} icon={item.icon} />;
})}
One of the most preferred icons utility is React-icons. You can simply install the npm package from here.
And you can view & search icons from here.
In the code you can use it like this, suppose you want to use AiFillHome icon, then just import it in the file like this,
import {AiFillHome} from "react-icons/ai";
And use it like
<AiFillHome />
You can check the props in the mentioned docs.
I am trying to make the weather app in Vite , but when I run the program I get the error "TypeError: Cannot read properties of undefined (reading 'main')". Below is part of the code:
<div id="app" :class="{warm: weather.main && weather.main.temp > 17}">
<main>
<div class="search-box">
<input type="text" class="search-bar" placeholder="Search..." v-model="query" #keypress="fetchWeather" />
</div>
<div class="weather-wrap" v-if="typeof weather.main != 'undefined'">
<div class="location-box">
<div class="location">
{{ weather.name }}, {{ weather.sys.country }}
</div>
<div class="date">
{{ dateBuilder() }}
</div>
</div>
<div class="weather-box">
<div class="temp">
{{ Math.round(weather.main.temp) }}°c
</div>
<div class="weather">{{ weather.weather[0].main }}</div>
</div>
</div>
</main>
</div>
This my js
export default {
name: "app",
date() {
return {
api_key: '803a7cd7089cd54e3ecc37bf1b6a3340',
url_base: 'https://api.openweathermap.org/data/2.5/',
query: 'Taiwan',
weather: {
main: {
temp: 17
}
},
}
my Error
enter image description here
I think the problem is this line:
<div id="app" :class="{warm: weather.main && weather.main.temp > 17}">
If you want to use js within the class="", You just have to prepend it by :, and not wrap it in {}.
Try changing that to:
<div id="app" :class="weather.main && weather.main.temp > 17 ? 'warm' : ''">
This will result in:
either
<div id="app" class="warm">
or
<div id="app" class="">
depending on the condition.
Also, a better way to check for optional properties is to use optional chaining as such:
<div id="app" :class="weather.main?.temp > 17 ? 'warm' : ''">
Below is a snippet of working code.
<script src="https://unpkg.com/vue#3"></script>
<div id="app">
<h1 :class="weather?.main?.temp > 17 ? 'warm' : 'cold'">{{query}}</h1>
</div>
<script>
const {
createApp
} = Vue
createApp({
data() {
return {
api_key: '803a7cd7089cd54e3ecc37bf1b6a3340',
url_base: 'https://api.openweathermap.org/data/2.5/',
query: 'Taiwan',
weather: {
main: {
temp: 18
}
},
}
}
}).mount('#app')
</script>
<style>
.warm {
color: red;
}
.cold {
color: blue;
}
</style>
<div id="app" :class="weather?.main?.temp > 17 ? 'warm' : ''">
<main>
<div class="search-box">
<input type="text" class="search-bar" placeholder="Search..." v-model="query" #keypress="fetchWeather" />
</div>
<div class="weather-wrap" v-if="weather.main != 'undefined'">
<div class="location-box">
<div class="location">
{{ weather.name }}
</div>
<div class="date">
{{ dateBuilder() }}
</div>
</div>
<div class="weather-box">
<div class="temp">
{{ Math.round(weather.main.temp) }}°c
</div>
</div>
</div>
</main>
</div>
export default {
name: "app",
data() {
return {
api_key: '803a7cd7089cd54e3ecc37bf1b6a3340',
url_base: 'https://api.openweathermap.org/data/2.5/',
query: '',
weather: {
main: {
temp: 0
},
},
}
},
So I am able to have four columns in single item at a time , but when I implement 'carousel' class (4th div in html file) then the first two item displays fine. But in the last item as it should only have 2 columns with task name 9 and 10, instead task name 1 and 5 are also displayed there.
if I don't implement carousel class then data displays fine but carousel buttons stops working.
' I've already tried different solutions provided on stack overflow. '
here is my HTML file
<!-- my tasks -->
<div class="row mt-3 mb-3">
<div class="col-md-12">
<!-- carousel -->
<div class="row mx-auto my-auto">
<div id="myTaskDiv" class="carousel slide w-100" data-ride="carousel">
<div class="carousel-inner w-100">
<!-- carousel item -->
<div class="carousel-item {{ i == 0 ? 'active' : '' }}" *ngFor="let chunkMyTask of productData ;let i =index;">
<!--widget-->
<div class="col-sm-6 col-md-4 col-lg-3" *ngFor="let myTask of chunkMyTask">
<div class="widget border">
<div class="widget-body">
{{myTask.name}}
</div>
</div>
<!--widget end-->
</div>
<!-- carousel item end-->
</div>
</div>
<!-- carousel controls -->
<a class="carousel-control-prev" role="button" href="#myTaskDiv" data-slide="prev">
<i class="fa fa-angle-left fa-3x" aria-hidden="true"></i>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" role="button" href="#myTaskDiv" data-slide="next">
<i class="fa fa-angle-right fa-3x" aria-hidden="true"></i>
<span class="sr-only">Next</span>
</a>
<!-- carousel controls end-->
</div>
<!-- carousel end -->
</div>
</div>
<!-- my tasks end-->
then this below is my .ts file
import { Component, OnInit } from '#angular/core';
import { task } from '../task';
import { TasksService } from '../tasks.service';
import { MyTaskServiceService } from 'src/app/dashboard/my-tasks/my-task-service.service';
#Component({
selector: 'app-my-tasks',
templateUrl: './my-tasks.component.html',
styleUrls: ['./my-tasks.component.css']
export class MyTasksComponent {
title = 'Carousel';
productData: any;
private myTasks: any;
private myTaskArray: any;
constructor(private myTaskService: MyTaskServiceService) { }
chunks(array, size) {
let results :any;
results = [];
while (array.length) {
results.push(array.splice(0, size));
this.num=this.num+1;
}
return results;
}
ngOnInit() {
this.myTaskService.get_New_Products().subscribe(
data => {
this.productData = this.chunks(data.json(), 4);
console.log(this.productData);
});
}
}
And at last this below is my json file:
[
{
"taskType": "myTask",
"name": "Task 1"
},
{
"taskType": "myTask",
"name": "Task 2"
},
{
"taskType": "myTask",
"name": "Task 3"
},
{
"taskType": "myTask",
"name": "Task 4"
},
{
"taskType": "myTask",
"name": "Task 5"
},
{
"taskType": "myTask",
"name": "Task 6"
},
{
"taskType": "myTask",
"name": "Task 7"
},
{
"taskType": "myTask",
"name": "Task 8"
},
{
"taskType": "myTask",
"name": "Task 9"
},
{
"taskType": "myTask",
"name": "Task 10"
}
]
I am using ui-grid in angular which has 5 columns. on hover of grid options columns are getting expanded towards right side.
Here is my file.
HTML File
<div class="full-panle-body">
<div class="row user-view-grid" ng-show="gridOptions.data.length > 0 && userLoaded">
<div ui-grid="gridOptions" ui-grid-auto-resize ui-grid-cellNav ui-grid-edit ui-grid-resize-columns ui-grid-pinning ng-style="getTableHeight()"></div>
</div>
<div class="row loading-spinner" ng-hide="userLoaded">
<div class="col-xs-3"></div>
<div class="loading col-xs-6">
<span rel='spinner' class='data-spinner'></span>
<div class="loading-text">{{::'label.loading.user.list' | translate}}</div>
</div>
<div class="col-xs-3"></div>
</div>
<div class="no-records" ng-show="!numberRecordsFound && userLoaded">
{{:: 'text.search.no.records' | translate }}
</div>
</div>
<!-- html template for status -->
<script type="text/ng-template" id="statusCell-template.html">
<div ng-click="grid.appScope.onUserDetails(row.entity)" class="inner-data-cell-center">
<div style="text-align:center;">
<i class="fa fa-envelope-o" aria-hidden="true" style="color:grey;" ng-show="'added' == row.entity.registrationStatus.toLowerCase()"></i>
<i class="fa fa-envelope-o" aria-hidden="true" style="color:blue;" ng-show="'notified' == row.entity.registrationStatus.toLowerCase()"></i>
<i class="fa fa-check" aria-hidden="true" style="color:green;" ng-show="'complete' == row.entity.registrationStatus.toLowerCase()"></i>
</div>
<div style="text-align:center;" class="smaller-grey">{{row.entity.registrationStatus}}</div>
</div>
</script>
<script type="text/ng-template" id="name-template.html">
<div class="ui-grid-cell-contents" ng-click="grid.appScope.onUserDetails(row.entity)">
<div class="name-style">{{row.entity.lastName}}, {{row.entity.firstName}}</div>
<div class="email-style">{{row.entity.email}}</div>
</div>
</script>
<!-- html template for organization -->
<script type="text/ng-template" id="organization-template.html">
<div class="single-elm-style" ng-click="grid.appScope.onUserDetails(row.entity)">
<span class="dummy">{{row.entity.organization}}</span>
</div>
</script>
<!-- html template for username -->
<script type="text/ng-template" id="username-template.html">
<div class="single-elm-style" ng-click="grid.appScope.onUserDetails(row.entity)">
<span>{{row.entity.userName}}</span>
</div>
</script>
<!-- html template for Account Status -->
<script type="text/ng-template" id="accountstatus-template.html">
<div class="single-elm-style" ng-click="grid.appScope.onUserDetails(row.entity)">
<span ng-show="row.entity.isActive">Enabled</span>
<span ng-show="!row.entity.isActive">Disabled</span>
</div>
</script>
CSS File
.ui-grid-row:hover{
border-left: solid 6px #hoverBlue;
}
JS File
$scope.gridOptions = {
rowHeight: 60,
multiSelect: false,
enableColumnMenus: false,
enableEdit: false,
enableSoring: true,
columnDefs: [
{
name: 'registrationStatus',
width: "15%",
displayName: 'Status',
headerCellClass: 'grid-header-center',
cellClass: 'grid-data-cell',
cellTemplate: 'statusCell-template.html'
},
{
name: 'lastName',
width: "30%",
displayName: 'Name',
headerCellClass: 'grid-header-left',
cellTemplate: 'name-template.html'
},
{
name: 'organization',
width: "15%",
displayName: 'Organization',
headerCellClass: 'grid-header-left',
cellTemplate: 'organization-template.html'
},
{
name: 'userName',
width: "20%",
displayName: 'Username',
headerCellClass: 'grid-header-left',
cellTemplate: 'username-template.html'
},
{
name: 'isActive',
width: "20%",
displayName: 'Account Status',
headerCellClass: 'grid-header-left',
cellTemplate: 'accountstatus-template.html'
}
]
};
Hi.I am using ui-grid in angular which has 5 columns. on hover of grid options columns are getting expanded towards right side.
I have googled for this problem and I found a lot of links which couldn't help me solve my problem. All I want to do is to send forms data to the controller. it goes to the controller but the data is not present in there.
here are my codes:
app.component.ts
import {Component, OnInit} from "angular2/core";
import {AsyncRoute, Router, RouteDefinition, ROUTER_PROVIDERS, RouteConfig, Location, ROUTER_DIRECTIVES, RouteParams} from "angular2/router";
import {CitiesComponent} from "./components/cities.component";
import { CitiesService } from './components/cities.service';
import { HTTP_PROVIDERS } from 'angular2/http';
import 'rxjs/Rx';
declare var System: any;
#Component({
selector: "app",
templateUrl: "/app/app.html",
providers: [CitiesService, HTTP_PROVIDERS, ROUTER_PROVIDERS],
directives: [ROUTER_DIRECTIVES]
})
export class AppComponent implements OnInit {
public routes: RouteDefinition[] = null;
constructor(private router: Router,
private location: Location) {
}
ngOnInit() {
if (this.routes === null) {
this.routes = [
new AsyncRoute({
path: "/City",
name: "City",
loader: () => System.import("app/components/cities.component").then(c => c["CitiesComponent"])
})
];
this.router.config(this.routes);
}
}
getLinkStyle(route: RouteDefinition) {
return this.location.path().indexOf(route.path) > -1;
}
}
cities.ts
export interface ICities {
Id: string;
State: string;
Title: string;
}
cities.component.ts
import {Component, OnInit} from "angular2/core";
import { FORM_DIRECTIVES } from 'angular2/common';
import { RouteParams, Router } from 'angular2/router';
import { ICities } from './cities';
import { CitiesService } from './cities.service';
#Component({
selector: "cities",
templateUrl: "/partial/cities",
directives: [FORM_DIRECTIVES]
})
export class CitiesComponent implements OnInit {
public City: ICities;
cities: ICities[];
errorMessage: string;
constructor(private _citiesService: CitiesService, private _router: Router,
private _routeParams: RouteParams) { }
ngOnInit() {
this._citiesService.getCities()
.subscribe(
cities => this.cities = cities,
error => this.errorMessage = <any>error);
//this.message = "anything!"
}
onSubmit(form: ICities): void {
console.log('you submitted value 23:', form);
this._citiesService.addCity(form);
}
}
cities.services.ts
import { Injectable } from 'angular2/core';
import { Http, Response, Headers, RequestOptions, RequestMethod, Request} from 'angular2/http';
import { Observable } from 'rxjs/Observable';
import { ICities } from './cities';
#Injectable()
export class CitiesService {
private _citiesInsert = '/Cities/CitiesInsert';
private _citiesList = '/Cities/GetCities';
constructor(private _http: Http) { }
getCities(): Observable<ICities[]> {
return this._http.get(this._citiesList)
.map((response: Response) => <ICities[]>response.json())
.do(data => console.log('All: ' + JSON.stringify(data)))
.catch(this.handleError);
}
addCity(city: ICities) {
let body = JSON.stringify({ city });
let headers = new Headers({ 'Content-Type': 'application/json' });
//let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
var url = '/Cities/CitiesInsert';
this._http.post(this._citiesInsert, JSON.stringify(city), headers)
.map(this.extractData)
.catch(this.handleError)
.subscribe(
(res2) => {
console.log('subsribe %o', res2)
}
);
}
private extractData(res: Response) {
let body = res.json();
alert("extract data: " + body);
return body.data || {};
}
private handleError(error: Response) {
// in a real world app, we may send the server to some remote logging infrastructure
// instead of just logging it to the console
alert("error: " + error);
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
cities.cshtml
<cities>
<div class="col-md-12">
<div class="portlet box blue ">
<div class="portlet-title">
<div class="caption">
<i class="fa fa-gift"></i> مشخصات
</div>
<div class="tools">
<a title="" data-original-title="" href="" class="collapse"> </a>
<a title="" data-original-title="" href="#portlet-config" data-toggle="modal" class="config"> </a>
<a title="" data-original-title="" href="" class="reload"> </a>
<a title="" data-original-title="" href="" class="remove"> </a>
</div>
</div>
<div class="portlet-body form">
<form role="form" #f="ngForm" (ngSubmit)="onSubmit(f.value)" >
<div class="form-body">
<div class="row">
<div class="col-sm-8">
<div class="form-group">
<label>وضعیت</label>
<select ngControl="State" class="form-control input-small selectpicker">
<option value="ACTIVATED" selected="selected">فعال</option>
<option value="DEACTIVE">غیرفعال</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-8">
<div class="form-group">
<label>عنوان</label>
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-envelope"></i>
</span>
<input class="form-control" ngControl ="Title" placeholder="عنوان شهر" type="text">
</div>
</div>
</div>
</div>
</div>
<div class="form-actions right">
<button class="btn">
<i class="fa fa-ban"></i> صرفنظر
</button>
<button class="btn green" type="submit">
<i class="fa fa-save"></i> ذخیره
</button>
</div>
</form>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="portlet mt-element-ribbon light portlet-fit ">
<div class="ribbon ribbon-right ribbon-clip ribbon-shadow ribbon-border-dash-hor ribbon-color-success uppercase">
<div class="ribbon-sub ribbon-clip ribbon-right"></div> لیست اطلاعات
</div>
<div class="portlet-title">
<div class="caption">
<i class="icon-layers font-green"></i>
<span class="caption-subject font-green bold uppercase">شهرها</span>
</div>
</div>
<div class="portlet-body">
<div class='table-responsive'>
<table class='table' *ngIf='cities && cities.length'>
<thead>
<tr>
<th>
Title
</th>
</tr>
</thead>
<tbody>
<tr *ngFor='#city of cities'>
<td>{{ city.Title }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</cities>
CitiesController.cs
[HttpPost]
public void CitiesInsert(Cities city)
{
Console.Write(city);
}
Try something like this:
<form [ngFormModel]="loginForm" (submit)="doLogin($event)"
and in your component
doLogin(event) {
console.log(this.loginForm.value);
event.preventDefault();
}