Paverskite savo svetainę vieno puslapio programa

Kai gausybė įrenginių, platformų ir naršyklių kiekvieną dieną auga, vieno puslapio programos (SPA) tampa vis labiau paplitusios. HTML5 ir „JavaScript“ dabar yra pirmos klasės piliečiai kurdami programas, taip pat keisdami tai, kaip mes kuriame ir kuriame puikias svetainių naudojimo galimybes naudodami CSS3.

Todėl tradicinis visapusiškos „skaitmeninės strategijos“ kūrimo modelis greitai keičiasi ir tampa racionalesnis. Tokios platformos, kaip „PhoneGap“, leidžia mums kurti programas HTML5 ir „JavaScript“ formatu, kurias vėliau galima pritaikyti ir sukompiliuoti įvairioms mobiliosioms platformoms („iOS“, „Android“, „Blackberry“ ir „Windows Phone“).

Tačiau vis dar išlieka spragos tarp kalbų ir sistemų, ypač tarp „programų“ kūrimo mobiliųjų ir planšetinių kompiuterių platformoms ir tradicinių, prieinamų ir pažangių svetainių kūrimo.



animuoti eilutę po efektų

Būdamas laisvai samdomas darbuotojas, aš patyriau klientų, norinčių pateikti svetainę, tada svetainę mobiliesiems, tada programą („Kingsmill Bread“ svetaines mobiliesiems ir staliniams kompiuteriams / planšetiniams kompiuteriams sukūriau MIT licencijuotoje, .NET pagrįstoje „Umbraco CMS“). „Tradicinis“ būdas tai padaryti pirmiausia būtų atlikti svetainę, naudojant reaguojantį (arba specialiai sukurtą) CSS išdėstymą, tada sukurti atskirą programą, kuri bus prijungta prie pagrindinės turinio parduotuvės.

Pjaustyta duona „Kingsmill Bread“ darbalaukio ir mobiliosios svetainės dalijasi turiniu naudodamosi „Umbraco CMS“, naudodamos konkrečius vartotojo agento šablonus.

Šis modelis puikiai veikia, jei turite „iOS“, „Java“ ir „Silverlight“ specialistų (taip, „Silverlight“ - džiaugsmai), tačiau nesikeičia, kai kalbama apie mastelio keitimą ir valdomumą. Vidutinės užsakytos programos kūrimo kainos (maždaug 22 000 svarų) ir vidutinės grąžos ( 400 svarų per metus, jei pasiseks ), ir staiga jūs pilate pinigus į baisiai didelę technologinę juodąją skylę.

O kaip su „JavaScript“?

„„ JavaScript “taupo dieną!“ Girdžiu, kaip frontend kūrėjai verkia. Ne taip greitai. „JavaScript“ išsprendžia daugumą tarpplatforminių problemų, tačiau tada jūs nebekuriate svetainės. „Google“ neindeksuoja turinio, įkrauto AJAX, todėl praradote prieinamumą ir laipsnišką patobulinimą: pagrindinius geros žiniatinklio architektūros principus.

Tradicinis skaitmeninės strategijos kūrimo modelis tampa daug racionalesnis

Ką aš girdžiu? „NodeJS taupo dieną! „JavaScript“ visur! “ Laikyk savo arklius ten, hipsterai. „NodeJS“ dar neturi „JavaScript“ pagrįsto TVS. 'O kaip su visomis tomis gražiomis, stabiliomis, brandžiomis turinio valdymo sistemomis, dėl kurių svetainės yra nuostabios jų turinio valdytojams?' Ar rimtai siūlote tiesioginį „WordPress“, „Drupal“, „Umbraco“ ir kt. Perkėlimą į „JavaScript“, kad tik išspręstumėte šią problemą? (Aš turėjau ką nors man pasiūlyti šį sprendimą „Scotch on the Rocks“ konferencijoje šiais metais, ir mano atsakymas buvo beveik toks pat.)

Taigi, kaip sukurti suprojektuotą svetainę, kuri būtų prieinama, ir tada ją „atnaujinti“, kad atrodytų, jaustųsi ir elgtųsi kaip SPA? Džiaugiuosi, kad to paklausėte, nes būtent tai ir sukursime šioje pamokoje.

Architektūra yra viskas, apžvelgsiu paprastą tinklaraščio svetainę, kurią galėsite toliau derinti pagal savo projektą. Pagal savo profesiją esu .NET bod, ir verta paminėti, kad ši pamoka yra iš dalies parašyta .NET, skirta serverio kodui. Jei tai jums nepatinka, dizaino modeliai lengvai pavirs jūsų pasirinkta MVC sistema - „Zend“, „CodeIgniter“, „Ruby“, „Django“ ir pan.

Atotrūkio mažinimas

Dauguma svetainių šiais laikais kuriamos naudojant modelio rodinio valdiklio (MVC) architektūrą, o programos, kurios remiasi pagal pareikalavimą įkeltais duomenimis, kuriamos naudojant modelio rodinio peržiūros modelio (MVVM) architektūrą. Abi paradigmos yra susijusios, tačiau įvykių tvarkymas šiek tiek skiriasi. Valdiklis turėtų atlikti veiksmus, susijusius su konkrečiu įvykiu (duomenų pateikimu), o peržiūros modelyje būtų nustatytas konkretus įvykis, skirtas tvarkyti vartotojo sąsajos atnaujinimus ir visus modelio privalomus pakeitimus (žmonės, žinantys C #, tai žinos kaip „INotifyPropertyChanged“ modelį).

Pagrindinis šios architektūros principas yra išsiaiškinti, kaip pasidalinti modeliu ir vaizdu tarp dviejų modelių. Kurdami savo svetainę tokiu būdu, 99,9 proc. Laiko jūsų peržiūros bus identiškos tiek serveryje, tiek kliente. Vienintelis skirtumas yra tai, kada ir kaip jie užpildomi modelio duomenimis - ar tai valdytojas serveryje, ar valdiklis kliente.

kaip padaryti plytelių tekstūrą

Pradėsime nuo paprastos svetainės (kurią galima atsisiųsti adresu netm.ag/demo-257) sukūrimo naudojant ASP.NET MVC 4. Jame yra pora valdiklių, modelis, sukurtas naudojant „Entity Framework“, kad parodytų pavyzdį serverio modelio populiacijos ir kai kurios peržiūros su reaguojančiu CSS3 šablonu, sukurtu naudojant „Bootstrap“. Jame yra viskas kairėje žemiau pateiktos diagramos pusėje - pagrindinis modelis, valdiklis ir pora rodinių, kad viskas būtų pradėta.

Abi pusės MVC ir MVVM dizaino modelių architektūra ir kaip mes

Abi pusės MVC ir MVVM dizaino modelių architektūra ir tai, kaip mes bandysime juos sujungti klientui ir serveriui

Tai vėjelis

Dabar mes ketiname įdiegti „AngularJS“ ir „BreezeJS“ į projektą. „NuGet“ („Visual Studio“ paketų tvarkyklė) leidžia tai lengvai įtraukti į mūsų projektą. „BreezeJS“ priklauso nuo „Q“, įrankio, leidžiančio ir valdančio asinchroninius „JavaScript“ pažadus.

Norėdami sukurti labai paprastą SPA patirtį iš mūsų esamos svetainės pagrindo, mes turime bendrinti maršruto lentelę MVC serveryje su „AngularJS“. Mes tai padarysime naudodami valdiklį, kuris supaprastina ir išspjauna maršruto lentelę tokiu kampu, kokį supranta kampinis. „Angular“ tikisi, kad maršruto duomenys bus sukonfigūruoti taip:

when('/blog', { templateUrl: 'partials/blog.html', controller: 'BlogListCtrl' }) .when('/blog/post/:blogId', { templateUrl: 'partials/blog-post.html', controller: 'BlogPostCtrl }) .otherwise({ redirectTo: '/index' });

Kaip matome iš šio kodo, „Angular“ maršrutų teikėjas tikisi žinoti ir valdiklį, ir atitinkamą vaizdą. Mes tieksime „AngularJS“ kaip bendrą valdiklį, kad patenkintume daugumą mūsų reikalavimų, tada išplėsime jį tam tikriems rodiniams (t. Y. Tinklaraščio sąrašui ir tinklaraščio įrašui, nes juose yra ne tik vanilės duomenys).

Norėdami tai padaryti, turime nustatyti, kurie valdikliai (ir atitinkami maršrutai) turi būti tiekiami iš serverio į kampinį. Čia mes pasinaudojame .NET atspindėjimo galimybėmis - kodu, kuris skaito kodą, arba „kodo priėmimu“, kaip man patinka galvoti. Įspėjimas: čia būk drakonai! Pažymėsime savo valdiklius serveryje.

Tai turi būti bendrinama su svetainės JS puse, naudojant metaduomenis, naudojant .NET funkciją „Reflection“, kad surinktumėte šiuos valdiklius. Šiuose valdikliuose pažymėsime savo veiksmus metaduomenimis, kad nustatytume atitinkamą JS vaizdą, modelį ir valdiklį, kaip parodyta diagramoje dešinėje.

Šis požiūris nėra patikimas. Jei maršrutuose arba valdiklio veiksmuose turite filtrų ar apribojimų, viską, ką teikia JS routeProvider, nes kampiniai maršrutai gali netekti serverio. Norėdami gauti daugiau informacijos apie pažangų MVC maršrutą, maršruto apribojimus ir filtravimą, labai rekomenduoju apsilankyti Scott Alleno kursuose Pluralsight ant ASP.NET MVC kamino .

Dalelė po dalelės

Dabar mes pateikėme „Angular“ savo maršruto lentelę, turime pradėti ją klijuoti. Pirma, mes atnaujiname savo valdiklius, kad paveldėtume iš mūsų bendrojo „RomanController“. Kai kurias to dalis mes nepaisysime vėliau, tačiau kol kas tai yra bendras žymeklis, leidžiantis nustatyti maršrutus ir URL, kuriuos norime, kad „Angular“ turėtų prieigą.

Tada turime pažymėti veiksmus, kuriuos norime pasiekti „AngularJS“, su pasirinktu atributu: RomanActionAttribute .

public class RomanDemoController : RomanController { private RomanSPA.Demo.Models.RomanSPAStarterKitEntities _context; public RomanDemoController() : base() { // Yes, I'm not using dependency injection for my DB context, cause this is a demo ;-) if (_context == null) _context = new Models.RomanSPAStarterKitEntities(); } [RomanAction] public ActionResult Index() { return View(new IndexModel()); } [RomanAction(Factory=typeof(BlogListFactory), ControllerName=”BlogController”, ViewPath=”/assets/blog-list.html”)] public ActionResult Blog() { return View(_context.BlogPosts); } [RomanAction(ControllerName=”BlogPostController”)] public ActionResult BlogPost(string slug) { if (_context.BlogPosts.Any(p => MakeTitleUrlFriendly(p.Title) == slug)) { return View(_context.BlogPosts.First(p => MakeTitleUrlFriendly(p.Title) == slug)); } else { return HttpNotFound(); } } [RomanAction] public ActionResult About() { return View(); } private string MakeTitleUrlFriendly(string title) { return title.ToLower().Replace(“ “, “-”); } }

Šis atributas yra veiksmo filtras ir turi tris parametrus, visus pasirenkamus: modelio gamyklą, valdiklio pavadinimą ir rodinio pavadinimą. Tai suteikia mūsų maršruto lentelei galimybę nurodyti bet kokį aiškų nepaisymą, kurio mes norime, arba pasirinkti bendrą numatytąjį elgesį (t. Y. Įkelti valdiklį be JSON modelio duomenų, kuris tada įkelia dalinį rodinį iš serverio). Atkreipkite dėmesį, kaip [RomanActionAttribute] galima automatiškai sutrumpinti iki [RomanAction] parengė C # kompiliatorius.

Esminė šio pratimo dalis yra ta, kad mes turėtume galimybę dalintis vaizdais ir atskleisti serverio duomenis, kad atliktume sudėtingas pertvarkas savo programoje. Tai reiškia, kad mes galime pasinaudoti HTML5 neprisijungus naudojamų talpyklų pranašumais, kad sukurtume puikią vartotojo patirtį programos pusėje.

Mes paliksime Indeksas ir Apie vaizdai tušti. Už „BlogList“ veiksmą, mes nurodysime gamyklos, pasirinktinį valdiklį ir pasirinktinį rodinį kliento pusėje. Veiksmui „BlogPost“ nurodysime pasirinktinį valdiklį, kad galėtume įkelti atskirą įrašą iš JSON, kurį gauname iš „BlogList“ gamyklos.

Dabar mes sukūrėme a „GenericController“ „AngularJS“, in / Programa / valdiklius ir „AppJS“ nustatėme automatinį maršrutą, kad visi maršrutai būtų pateikti iš serverio į klientą. Jūs galite pateikti papildomų maršrutų rankiniu būdu, perkrausdami RoutesApiController ir viršijantis „ExtraRoutes“ nuosavybę su savo pasirinktu maršrutų, kuriuos reikia nuvykti į AngularJS, sąrašu.

angular.module('RomanSPA', ['ngRoute']) .config(['$routeProvider', function ($routeProvider, $locationProvider) { $.ajax({ url: '/api/RouteApi/AllRoutes', success: function (data) { for (var i = 0; i < data.length; i++) { $routeProvider.when(data[i].RoutePattern, { controller: data[i].controller, templateUrl: data[i].templateUrl }); } $routeProvider.otherwise({ redirectTo: '/' }); }, fail: function (data) { } }); }]) .value('breeze', window.breeze);

Pagrindinės funkcijos

Galiausiai „GenericController“ įdiegėme dvi pagrindines funkcijas - vieną, kad rankiniu būdu pritaikytume nurodytą šabloną, ir vieną, kad gautume modelį naudodamiesi gamykloje esančiame atribute action.

angular.module('RomanSPA') .controller('GenericController', ['$scope', '$route', function ($scope, $route){ $scope.pageUrl = '/'; if ($route.current !== undefined) { $scope.pageUrl = $route.current.templateUrl; } // Retrieve our view - be it from server side, or custom template location $.get({ url: $scope.pageUrl.toString(), beforeSend: function(xhr) { xhr.setRequestHeader('X-RomanViewRequest', 'true'); }, success: applyView }); // Retrieve our model using the modelfactory for our current URL path $.get({ url: $scope.pageUrl.toString(), beforeSend: function (xhr) { xhr.setRequestHeader('X-RomanModelRequest', 'true'); }, success: applyModel }); function applyView(data) { $scope.$apply(function () { angular.element('body').html($compile(data)($scope)); }); } function applyModel(data) { $scope.model = data; } } }]);

Galiausiai mes esame taške, kur:

  • Surinkome visus maršrutus serveryje, kuriais norime pasinaudoti „AngularJS“. Kai bus paleista programa, jie bus eksportuoti į „Angular“ maršruto parinkimo biblioteką.
  • Mes nurodėme bendrą valdiklį, kurį gali paveldėti konkretūs mūsų valdikliai. Tačiau tai reiškia, kad mes turime „bendrąjį“ SPA funkcionalumą, kai puslapiai dalinai įkeliami naršant svetainėje.
  • Vaiko veiksmus, prie kurių galbūt norime, kad „AngularJS“ turėtų prieigą, bet kurie neturėtų būti nukreipimo lentelėje (pvz., Navigacija, poraštė ir kiti daliniai rodiniai), galima pažymėti [RomanPartial] .
  • Prašymas / RomanDemo / Index suteiks mums visą puslapį, bet kai „AngularJS“ to paprašys, jis pateiks dalinį vaizdą arba JSON objektą, priklausomai nuo mūsų pateiktų metaduomenų.
  • Veiksmai, kuriems norime nurodyti metaduomenis (arba eksportuoti į kampinį nukreipimą), t. Y. Pasirinktinis JSON modelis, pasirinktinio šablono URL arba pasirinktinis „AngularJS“ valdiklis, yra pažymėti [RomanAction] .

Mes beveik pasiruošę. Čia mes sukursime „BlogController“, kuris paveldės iš to, kokia kryptimi galite eiti naudodamiesi savo hibridinės svetainės programa. „GenericController“ , ir naudokite tai norėdami surinkti visus tinklaraščio įrašus. Tada tai naudosime kaip būdą suteikti vartotojams galimybę naršyti tinklaraštyje, o didžioji dalis duomenų mums saugoma HTML5 neprisijungus saugomoje vietoje.

angular.module('RomanSPA') .controller('BlogController', ['$scope', function ($scope) { $controller('GenericController'); function storePostsOffline(data) { if (!supportsLocalStorage()) { return false; } localStorage[“RomanSPA.data.blog.posts”] = data; return true; } var manager = new breeze.EntityManager('/breeze/BlogApi'); var query = new breeze.EntityQuery('BlogPost'); manager.executeQuery(query) then(function(data) { storePostsOffline(data); $scope.

HTML5 saugykla neprisijungus yra didžiausia priežastis, dėl kurios norite tai padaryti. Taip pat galite išplėsti rodinio variklį, kad šablonai ir rodiniai būtų automatiškai saugomi neprisijungus. Tai darydami jūs leidžiate savo svetainės lankytojui elgtis su savo svetaine panašiau į programą, kurią jie gali naudoti net ir neturėdami „WiFi“ ar telefono signalo.

Apvyniojimas

Dabar turime:

  • Pagrindinė MVC svetainė su pagrindinių puslapių maršrutais ir tinklaraščiu.
  • Viršuje sėdinti MVC programa, veikianti „AngularJS“, su atitinkama maršruto lentele.
  • „AngularJS“ teikia AJAX užklausas naudodamas „jQuery“, kurią serverio pusės MVC interpretuoja, kad tinkamai grąžintų JSON modelį arba HTML rodinį.

Šio maišymo rezultatas? ASP.NET MVC RomanSPA sistema! (nebūtinas vėmiklis, pjautuvo grandikliai ir sieros skonio vanduo). Galite naudoti šį pagrindą kurdami daug sudėtingesnių savo svetainės dalių.

Pagrindinė „AngularJS“, „KnockoutJS“ ar „BreezeJS“ sistema ir plėtiniai buvo „susieti“ su atskirais projektais. Galite įdiegti „AngularJS“ arba „KnockoutJS“ leidimus, kurie padės jums nedelsiant pradėti diegiant visas būtinas išankstines bibliotekas, arba galite tiesiog įdiegti šerdį ir parašyti savo plėtinius, skirtus „EmberJS“ ar bet kokiai kitai „MVx JavaScript“ sistemai, kuri jums reikalinga. išgalvotas.

Žodžiai: Benjaminas Howarthas

kaip animuoti fotošopo sluoksnius po efektų

Benjaminas Howarthas yra „Microsoft .NET“ kamino atvirojo kodo sistemų ekspertas. Šis straipsnis pirmą kartą pasirodė tinklinis žurnalas 257 leidimas.