πŸ“œ ⬆️ ⬇️

The threshold for entry into Angular 2 - theory and practice

Good afternoon, dear Habra: residents, readers, writers, negative commentators.

As an introductory part and to remove some questions, I will tell you a little about myself. My name is Tamara. Ouzhas, I'm a girl! Who it scares - close the article and do not read.

For the rest: I’ve gotten unfinished 10 years ago at MIREA, the faculty of cybernetics. But all these 10 years of practice have developed in such a way that for the most part I was engaged in advertising and during breaks it happened to work in various startups related to the Internet and not only.
')
image

In general, if it is short, then the Chukchi is not a programmer, the Chukchi simply respects with his heart and soul those who, from obscure lines of code, do amazing things that work well.

I’m sorry if I say that I can’t figure it out in someone else’s code. I can, on java and php I can even fix some simple things. But beyond this, my programming experience never went away.

image

But this is not the case, the soul asked for poetry from scratch. And having stopped my labor activity for some time and having taken a long vacation for my soul and body, I decided to try to do something with 0 and on my own. By β€œsomething” I understand my little project.

When I thought and chose what to do, I stopped at PHP for the backend. Or rather on the framework - Laravel.
I stopped at it for the reason that for me it seemed to be the lowest on the threshold of entry. I do not like the documentation in it, since from my point of view many moments are not disclosed and I have to go into the source to read the comments. But the main common points dismantled on many resources. Laracasts as a source of learning is very sad. Taylor there considers everything rather superficially, jumping from one to another and completely without going deep. All tops.

For the frontend, I chose Angular 2. Yes, I know that it is in beta mode :), but again it seemed logical to me.
To enter Angular2 I use their documentation, source code on github, reading the issue there, stackoverflow - but somehow everything is sad now - they mostly ask questions in the documentation.

Well, probably with the introduction I will finish.
I turn now to the point. Below I will share my little experience, what I did and how long I managed to do it.

image

There will be no examples of todo and helloworld.
I will show a small example of what I’m picking and how it works for me.
In the piece will receive data through api, output them, and send the form.

Configure Angular 2 and Laravel.


. Angular 2 β€” 5- HelloWorld.
Laravel .

, .

. , Angular public, . Laravel , Angular , c . laravel . , api() . , .
, , . , , : api.proect.dev, : proect.dev

sanex3339 Angular 2 Laravel 5.
!
, : , .

- , Angular, API.


, 2 . , :) , :)
, .

-
php artisan make:model MainCategory -m

Mainategory .
.

-
2016_02_22_135455_create_main_categories_table.php

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateMainCategoriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('main_categories', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name', 255)->unique(); //     . 
            $table->string('slug', 255)->unique(); //    
            $table->boolean('show')->default(0); //      .  true(1) -  ,  false(0) - .
            $table->timestamps();
            $table->softDeletes();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('main_categories');
    }
}


-
MainCategory.php

<?php
namespace App\Models\Catalog;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

/**
 * Class MainCategory
 *
 * @package App
 *
 * @property integer  $id $primaryKey $autoincrement
 * @property string   $name $unique
 * @property string   slug $unique
 * @property boolean  show
 * @property datetime created_at
 * @property datetime updated_at
 * @property datetime deleted_at
 */
class MainCategory extends Model
{
    use SoftDeletes;

    protected $fillable = ['name', 'slug', 'show'];

    protected $guarded = ['id'];

    protected $dates = ['created_at', 'updated_at', 'deleted_at'];

}


, php , , . php artisan make:controller MainCategoryController
Catalog, , .
, - , :)

-
MainCategoryController.php

<?php

namespace App\Http\Controllers\Catalog;

use App\Models\Catalog\MainCategory;
use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

/**
 * @api
 * @package     App\Http\Controllers\Catalog
 * @class    MainCategoryController
 */
class MainCategoryController extends Controller
{
    /**
     *        
     * @function indexAdmin
     * @return mixed $main_categories
     */
    public function indexAdmin()
    {
        $main_categories = MainCategory::all();
        return $main_categories;
    }

    /**
     * @function createAdmin
     *    .     
     *
     * @param Request $request
     */
    public function createAdmin(Request $request)
    {
        $main_category = new MainCategory;
        $main_category->name = $request->name;
        $main_category->slug = $request->slug;
        $main_category->show = $request->show;
        $main_category->save();
    }
}


, β€” . route.php 2 .

Route::group(['middleware' => 'cors'], function() {
    Route::group(['middleware' => 'api'], function () {
            Route::group(['prefix' => 'backend'], function () {
                Route::group(['namespace' => 'Catalog', 'prefix' => 'catalog'], function () {
                    Route::get('/main-categories', 'MainCategoryController@indexAdmin');
                    Route::post('/main-category/create', 'MainCategoryController@createAdmin');
                });
            });
    });
});



2 :

get: http://api.project.dev/backend/catalog/main-categories
post: http://api.project.dev/backend/catalog/main-category/create

.

! Angular 2.


.
, , . , habra .ts , html.
image

β€” . . , , main.ts boot.ts :)

index.html
, , ,

<script src="node_modules/angular2/bundles/router.dev.js"></script>
<script src="node_modules/angular2/bundles/http.dev.js"></script>

- API.

index.html
<html>
<head>
    <base href="/">
    <title>Angular 2 QuickStart</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- 1. Load libraries -->
    <!-- IE required polyfills, in this exact order -->
    <script src="node_modules/es6-shim/es6-shim.js"></script>
    <script src="node_modules/systemjs/dist/system-polyfills.js"></script>
    <script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>
    <script src="node_modules/angular2/bundles/router.dev.js"></script>
    <script src="node_modules/angular2/bundles/http.dev.js"></script>
    <!-- 2. Configure SystemJS -->
    <script>
        System.config({
            packages: {
                app: {
                    format: 'register',
                    defaultExtension: 'js'
                }
            }
        });
        System.import('app/boot')
                .then(null, console.error.bind(console));
    </script>
</head>
<!-- 3. Display the application -->
<body>
<shop-app>Loading...</shop-app>
</body>
</html>


2 : , .

app.component.ts. , , <shop-app></shop-app> .

app.component.ts
import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS} from "angular2/router";
import {HomePageComponent} from "./home-page/home-page.component"
import {DashboardMainCategoryComponent} from "./dashboard/catalog/main-category/main-category.root.component";

@Component({
    selector: 'shop-app',
    template: `
    <a [routerLink]="['HomePage']"></a>
    <a [routerLink]="['/DashboardMainCategory']"></a>
    <router-outlet></router-outlet>
    `,
    directives: [ROUTER_DIRECTIVES],
    providers: [ROUTER_PROVIDERS]
})

@RouteConfig([
    {
        path: '/',
        name: 'HomePage',
        component: HomePageComponent,
        useAsDefault: true
    },

    {
        path: '/main-category',
        name: 'DashboardMainCategory',
        component: DashboardMainCategoryComponent
    }

])
export class ShopAppComponent { }


, - β€” : HomePageComponent DashboardMainCategoryComponent.

HomePageComponent - home-page.component.ts
import {Component} from "angular2/core";

@Component({
    selector: 'home-page',
    template: '<h1> </h1>'
})

export class HomePageComponent {}


DashboardMainCategoryComponent - main-category.root.component.ts
import {Component} from "angular2/core";

@Component({
    selector: 'dashboard-main-category',
    template: '<h1></h1>'
})

export class DashboardMainCategoryComponent {}


, . boot.ts ShopAppComponent.

boot.ts
:) , , app.component.ts

boot.ts
import {bootstrap} from 'angular2/platform/browser'
import {ShopAppComponent} from "./app.component";

bootstrap(ShopAppComponent);


. , npm run start, .

β€” , .

, , . , , .

MainCategory


- β€” php, pojo β€” java.
: main-category.ts

main-category.ts
export class MainCategory{
    constructor(
        public id: number,
        public name: string,
        public slug: string,
        public show: boolean,
        public created_at: string,
        public updated_at: string,
        public deleted_at: string
    ) {}
}


, β€” , API.

β€” string. β€” , . , .

MainCategoryService


, . . ARCHITECTURE OVERVIEW Angular2, , , - (, , , , β€” API) service , , . , . . main-category.service.ts

main-category.service.ts
import {Injectable} from "angular2/core";
import {Http, Headers, RequestOptions, Response} from "angular2/http";
import {Observable} from "rxjs/Observable";
import 'rxjs/Rx'; //        API   .  ,     
import {MainCategory} from "./main-category";

//@Injectable - ,      .
@Injectable()
export class MainCategoryService {

    constructor (private http: Http) {}

    //          ,    2    .      ,          :) 
    private _getAdminMainCategories = 'http://api.shops.dev:8080/backend/catalog/main-categories';
    private _createAdminMainCategory = 'http://api.shops.dev:8080/backend/catalog/main-category/create';

   //    
   getAdminMainCategories() {
        //  API  get
        return this.http.get(this._getAdminMainCategories)
                        //       .    -    json 
                        .map(res => <MainCategory[]> res.json())
                        .catch(this.handleError);
    }

    //  .             ,   ,     
    createAdminMainCategory(name:String, slug:String, show:boolean) : Observable<MainCategory> {
        //   JSON-. ,        
        let body = JSON.stringify({name, slug, show});
        //   
        let headers = new Headers({ 'Content-Type': 'application/json' });
        let options = new RequestOptions({ headers: headers });

        // 
        return this.http.post(this._createAdminMainCategory, body, options)
            .map(res =>  <MainCategory> res.json())
            .catch(this.handleError)
    }

    private handleError (error: Response) {
        //in a real world app, we may send the error to some remote logging infrastructure
        //instead of just logging it to the console
        console.error(error);
        return Observable.throw(error.json().error || 'Server error');
    }
}


. β€” !

GetMainCategories


, : main-category.get.component.ts

main-category.get.component.ts`
import {Component} from "angular2/core";
import {MainCategoryService} from "./main-category.service";
import {OnInit} from "angular2/core";
import {MainCategory} from "./main-category";

@Component({
    selector: 'backend-get-main-categories',
    templateUrl: 'app/dashboard/catalog/main-category/main-category.get.template.html',
    providers: [MainCategoryService] //        
})

export class BackendGetMainCategories implements OnInit {

    constructor (private _mainCategoryService: MainCategoryService) {}

    errorMessage: string;
    mainCategories: MainCategory[];

    ngOnInit() {
        this.getAdminMainCategories();
    }
    //    ,   getAdminMainCategories
    getAdminMainCategories() {
        this._mainCategoryService.getAdminMainCategories()
                                .subscribe(
                                    mainCategories => this.mainCategories = mainCategories,
                                    error => this.errorMessage = <any>error
                                );
    }
}


main-category.get.template.html
<h1> </h1>
<table>
    <thead>
    <tr>
        <th>id</th>
        <th>name</th>
        <th>slug</th>
        <th>show</th>
        <th>created_at</th>
        <th>updated_at</th>
        <th>deleted_at</th>
    </tr>
    </thead>
    <tbody>
   <!--Angular            :)-->
    <tr *ngFor="#mainCategory of mainCategories">
        <td>{{ mainCategory.id }}</td>
        <td>{{ mainCategory.name }}</td>
        <td>{{ mainCategory.slug }}</td>
        <td>{{ mainCategory.show }}</td>
        <td>{{ mainCategory.created_at }}</td>
        <td>{{ mainCategory.updated_at }}</td>
        <td>{{ mainCategory.deleted_at }}</td>
    </tr>
    </tbody>
</table>


PostMainCategory


Angular2 β€” template data-driven. , template β€” . .. Angular1. Data-driven β€” Angular2 . . , , . β€” . .

main-category.create.component.html
import {Component} from "angular2/core";
import {MainCategoryService} from "./main-category.service";
import {OnInit} from "angular2/core";
import {FORM_DIRECTIVES} from "angular2/common";
import {FORM_PROVIDERS} from "angular2/common";
import {ControlGroup} from "angular2/common";
import {FormBuilder} from "angular2/common";
import {Validators} from "angular2/common";
import {MainCategory} from "./main-category";
import {HTTP_PROVIDERS} from "angular2/http";

@Component({
    selector: 'backend-create-main-category',
    templateUrl: 'app/dashboard/catalog/main-category/main-category.create.component.html',
    providers: [MainCategoryService, FORM_PROVIDERS, HTTP_PROVIDERS],
    directives: [FORM_DIRECTIVES]
})

export class BackendCreateMainCategory implements OnInit {
    //             :) 
    createMainCategoryForm: ControlGroup;
    mainCategories:MainCategory[];
    errorMessage: string;

    constructor( private _formBuilder: FormBuilder, private _mainCategoryService: MainCategoryService) {}

      //     -     
      ngOnInit() {
        this.createMainCategoryForm = this._formBuilder.group({
            'name': ['', Validators.required],
            'slug': ['', Validators.required],
            'show': [false]
        });
    }

     //      
     onSubmit() {
        var name = this.createMainCategoryForm.value.name;
        var slug = this.createMainCategoryForm.value.slug;
        var show = this.createMainCategoryForm.value.show;
        this._mainCategoryService.createAdminMainCategory(name, slug, show).subscribe(
          main_category => this.mainCategories.push(main_category),
            error => this.errorMessage = <any>error
        );

    }


main-category.create.template.html
<h1>  </h1>

<form [ngFormModel]="createMainCategoryForm" (ngSubmit)="onSubmit()">
    <div>
        <label for="name"></label>
        <input type="text" id="name" [ngFormControl]="createMainCategoryForm.controls['name']">
    </div>
    <div>
        <label for="slug"></label>
        <input type="text" id="slug" [ngFormControl]="createMainCategoryForm.controls['slug']">
    </div>
    <div>
        <label for="show">?</label>
        <input type="checkbox" id="show" [ngFormControl]="createMainCategoryForm.controls['show']">
    </div>
    <button type="submit"></button>
</form>


radiobutton Angular2 , , , checkbox.

DashboardMainCategoryComponent. :

main-category.root.component.ts
import {Component} from "angular2/core";
import {FORM_DIRECTIVES} from "angular2/common";
import {ControlGroup} from "angular2/common";
import {Control} from "angular2/common";
import {FormBuilder} from "angular2/common";
import {Validators} from "angular2/common";
import {MainCategoryService} from "./main-category.service";
import {HTTP_PROVIDERS} from "angular2/http";
import {BackendGetMainCategories} from "./main-category.get.component";
import {BackendCreateMainCategory} from "./main-category.create.component";
@Component({
    selector: 'dashboard-main-category',
    template:`
    <h1></h1>
    <backend-get-main-categories></backend-get-main-categories> 
    <backend-create-main-category></backend-create-main-category>
    `,
    directives: [
        FORM_DIRECTIVES,
        BackendGetMainCategories,
        BackendCreateMainCategory],
    providers: [MainCategoryService, HTTP_PROVIDERS]
})

export class DashboardMainCategoryComponent {}


.


, , :
Backend β€” 1 17 . , PhpStorm, . , php .
Angular2 .
JS. , , β€” , . Angular2, JavaScript, TypeScript, , , , 12 48 . , , - IDE .

: IMHO Angular2 , , , - , HelloWorld ToDo-.

P.S. , β€” Angular2. , , . - , , , .

P.P.S. , , , , - β€” :)

: , , , β€” . .

, !

Source: https://habr.com/ru/post/278523/


All Articles