Tag Archives: controller

Angular 2 Tutorial – movies App

Last time I wrote a blog created the MovieAPI and now I am using that API as back end services to create an angular 2 app.

the final source code could find at my github repository.  here is the link download

For the MovieAPI open it, build it will install the packages automatically, then run the service first.

After the service is done, go to the angular2 folder, open command window

–run npm install,

— npm start

It will look like this:

home

create.PNG

added

Step 1 : Setting up your angular 2 application, I already have a blog  click here to found it. Or also could download from the source file from https://github.com/angular/quickstart/blob/master/README.md but it add a lot of unnecessary setting, probably confuse for beginning learner.

It was better do few times manually setting it up to get understand all of the necessary for start anguar 2 application.

Step 2:  In angualr 2 everything is component, for me normally like to create the service first. I just create a file named movies.service.ts under folder movies


import {Injectable} from 'angular2/core';
import {IMovie} from './movie';
import {Http, RequestOptions , Response, Headers} from 'angular2/http';
import {Observable} from 'rxjs/Observable';

@Injectable() 
export class MovieService {   
    private _movieUrl = 'http://localhost:53871/api/movies';

    constructor(private _http: Http) { }

    getMovies(): Observable<IMovie[]> {
        return this._http.get(this._movieUrl)
            .map((response: Response) => <IMovie[]>response.json()) //arrow function, tranceform response to json object and is array of IMovie[]
            .do(data => console.log("All: " + JSON.stringify(data))) //for debug
            .catch(this.handleError);
    }


    createMovie(movie: IMovie): Observable {
        let body = JSON.stringify(movie); 
        let headers = new Headers({ 'Content-Type': 'application/json' });
        let options = new RequestOptions({ headers: headers });

        return this._http.post(this._movieUrl, body, options)               
                .map(this.extractData)
                .catch(this.handleError);
    }

    private extractData(res: Response) {
        let body = res.json();
        return body.data || {};
    }

    private handleError(error: Response) {
        console.error(error);
        return Observable.throw(error.json().error || 'Server error');
    }
}

In there MovieService I have a IMovie here is my movie.ts I put it in the same folder with MovieService .


//interface won't compile to js file, it just for typescript do type checking
 export interface IMovie { 
    movieId: number;
    title: string;
    genre: string;
    classification: string;
    releaseDate: number;
    rating: number;
    cast: string[];

}


export class Movie implements IMovie {
    movieId: number;
    title: string;
    genre: string;
    classification: string;
    releaseDate: number;
    rating: number;
    cast: string[];
}

Step 3: Inject the services.
Go to the app.component.ts this is our container component, for anguar 2 only need inject once, then all of the nest container could using it ( by import it ).

Inject a service has two steps:

1) import the file into the app.component,

2) Inject it as providers

here is my app.component.ts

angular2_injection

Step 4: Create the movies-list.component.ts


//for using component, simply import it into this file
import {Component, OnInit} from 'angular2/core';
import { ROUTER_DIRECTIVES } from 'angular2/router';

import {IMovie} from './movie';
import {MovieService} from './movies.service';
import {MovieFilterPipe} from './movie-filter.pipe';
import { StarComponent } from '../shared/star.component';

@Component({
    selector: 'sz-movies',
    templateUrl: 'app/movies/movies-list.component.html',
    styleUrls: ['app/movies/movies-list.component.css'],  
    pipes: [MovieFilterPipe],
    directives: [StarComponent, ROUTER_DIRECTIVES]
   
})
export class MovieListComponent implements OnInit {
    pageTitle: string = 'Movie List';   
   
    listFilter: string;
    errorMessage: string;
    movies: IMovie[];


    constructor(private _movieService: MovieService) {

    }
    
    ngOnInit(): void {
        this._movieService.getMovies()
            .subscribe(
            movies => this.movies = movies,
            error => this.errorMessage = error);
    }

}

here is the movies-list.component.htmlmovies_html

 

for this component I have a nested StarComponent.

Setp 5: create nested StarComponent, here is the star.component.ts under the share folder


import { Component, OnInit, Input} from 'angular2/core';
@Component({
    selector: 'sz-star',
    templateUrl: 'app/shared/star.component.html',
    styleUrls: ['app/shared/star.component.css']
})
export class StarComponent implements OnInit {
    @Input() rating: number;
    starWidth: number;
    ngOnInit(): void {
        this.starWidth = this.rating * 86 / 5;
    }
}

star.component.htmlstar.PNG

css:

star_css

In angular 2: data flow is unidirectional, for passing data from view to the class

first: you passing data into the directive could bind it to the property

passing_data_down.PNG

Second: need import the Input from angular2/core, and bind it to the property

inData

Now, one nested movies-list.component and nested star.componet down.

Now using the same steps create the MovieCreateComponent


import {Component, OnInit} from 'angular2/core';

import {IMovie, Movie} from '../movie';
import {Router} from 'angular2/router';
import {MovieService} from '../movies.service';

@Component({
    templateUrl: 'app/movies/create/movie-create.component.html'
})

export class MovieCreateComponent implements OnInit {
    title: string = 'Create New Movie';
    newMovie: IMovie;

    constructor(
        private _moviesService: MovieService,
        private _router: Router
    ) { }

    ngOnInit() {
        this.newMovie = new Movie;
    }

    createMovie(event) {
        let _this = this;

        this._moviesService.createMovie(this.newMovie)
            .subscribe(function () {
                _this._router.navigate(['Movies']);
            });
    }

    cancelCreate(event) {
        this._router.navigate(['Movies']);
    }

}angular2_form.PNG
Router:
route.PNG

In the index.html page, put the baseurl:
baseUrl.png

Done, have fun!

Advertisements

Using viewbag pass data to the view and bind it to my dropdownlist.

In my booking view I has a dropdownlist need bind to my database table, In this tast I just use viewbag. I know it is good habit bind the view to your viewmodel, but sometime you need do some nasty thing to get the job quickly done. So here is the code in my controller to retrive the data and pass it to the viewbag.

retrevedatafromdatabses

here I pass to SelectLists to my view.

I my view you just need this one line of code to get it.

@Html.DropDownList(“SydneySuburb”, null, “Select »”, new { @id = “to_suburb” })

@Html.DropDownList(“SydneySuburb”, null, “Select »”, new {  @id = “from_suburb” })

the dropdown is look like this

dropdownlistcontroller

Simple isn’t it!!!

First I tried to do this, I search internet, there are expert write it in very complexed way. The expert alway like to write it like that to make them looking like expert( in my view).

here I just figure it out in very simple way.

Have fun!

JQuery Auto complete work with bakcode by using asp.net mvc

Recently to convert the new website, I have a bookinng form for the clients to finished the booking,there is some exiting data need to using auto complete. In the past I alway use ajax tool control kits to achieve that result. But now I am kind of fun for JQuery. Here is the Jquery Autocomplete textbox

First I have databses contain all the subuerbs, here is my database table.

databaseSuburbs

here is my action in my BookController:

databseJasonResult

I let it return json because json is the fast and easy analyse data at moment.

Then in your view , just add the reference to JQuery UI:

autocompleteJqury

You could ignore the timepicker.min.css, and timepicker.min.js, I use it to picker up the time, for autocomplete don’t need those two references.

here just in you view you just need one more line.

@Html.TextBox(“SearhToSuburb”, null, new {type=”text”,@class=”form-control”, @id = “search_to_suburb” })

That’s it. Simply isn’t it. Have fun. Below is what will it looking like.feels

Using two Way Adding “active” tag to your navigation list in an asp.net mvc Layout page

Recently my task need convert this website http://www.royalecoach.com.au/royale.asp (this is wrote by using classic asp) into asp.net MVC.

First I need to create a layout.cshtml for my the new version of this website.Then navigation need add a class named active to it when the action method has been called.

The first way is very simpley, you could wirte a logic to your view, here is one solution:

addClassNametoLi

But the rule of MVC is the view must be simply as possible, I don’t like this nasty and yuck c# code sit in there. So there is a way just by write a CustomHtmlHelpers to improve it.

here is my class file:

htmlHelper

 

Then in your layout page ,your could use it like:

layoutMenu

That’s it. By the way, I am using asp mvc4. Hope that could help some one else.

Have fun:)

Basic struction — create Database first ASP MVC Application(Models in three way)

Here in the internet have a lot tutorial introduction about create code first asp mvc application, but in the real life world the database always aready is exsiting. I am not mvc experter, I am fresher now. It took me a while to get the basic struction a while.So I like to write it down wish this could help some people like me struggling in the beginning.

OK, let me asume that we are going to create a online store ecormmerce website.

Way one: basic struction

Then you create a new MVC project through VS2013, first thing is add a connection string to your root web.config file.

It is like this:connectionStr

Modelsisnothingjustclassfile

Models is nothing just class file. You map your table to class file, then when you create a controller you could select strongly type.

finally is the Add one line to Global.asax to stop populater some seed data

GlobalNeedAddOneLine

See the null meaning don’t popular seed data.

Way two: basic struction(Models is another project)

I won’t talk about the controller or the views. But Models could anything, Web services, WCF and don’t sit in your project, the model is not neccessary sit in your project.So your project only have controller and Views, but the Models is independent. Here is a simple practise I did in my Demo struction is like this:

separateModelMvc

Way three: basic struction(Model is your entity Framework)

MvcEntityFrameworkStruction

How to create Picture Upload by using ASP MVC 4

This is a very simply example for how to using asp MVC. In this example doesn’t involved with your database. So start from create a model here is your code for your picture upload model. model is cs file, so save below code as PictureModel.cs


using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace MvcDemo.Models
{
    public class PictureModel
    {
        [Required]
        public HttpPostedFileBase PictureFile { get; set; }
    }
}

Then create a action event to your Controller. Controller also just cs file, so save below to one of the Controllers file


//by default, this will be called by get 
public ActionResult PictureUpload()
        {
            return View();
        }

here is the view file code. view is the PictureUpload.cshtml


@model MvcDemo.Models.PictureModel
@{
    ViewBag.Title = "Picture Upload";
}


Picture Upload

@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = “multipart/form-data” })) { @Html.AntiForgeryToken() @Html.ValidationSummary(true)

PictureModel 

@Html.LabelFor(model => model.PictureFile)

 

@Html.TextBoxFor(model => model.PictureFile, new { type = “file” }) @Html.ValidationMessageFor(model => model.PictureFile)

} @section Scripts { @Scripts.Render(“~/bundles/jqueryval”) }

After submit, it will call the post, below is the action event for post


[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult PictureUpload(PictureModel model)
        {
            if (model.PictureFile.ContentLength > 0)
            {
                var fileName = Path.GetFileName(model.PictureFile.FileName);
                var filePath = Server.MapPath("~/Content/Uploads");
                string savedFileName = Path.Combine(filePath, fileName);
                model.PictureFile.SaveAs(savedFileName);                
            }
            return View(model);
        }