程序員必知的前端演進(jìn)史_第1頁(yè)
程序員必知的前端演進(jìn)史_第2頁(yè)
程序員必知的前端演進(jìn)史_第3頁(yè)
程序員必知的前端演進(jìn)史_第4頁(yè)
程序員必知的前端演進(jìn)史_第5頁(yè)
已閱讀5頁(yè),還剩14頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、程序員必知的前端演進(jìn)史細(xì)細(xì)整理了過去接觸過的那些前端技術(shù),發(fā)現(xiàn)前端演進(jìn)是段特別有意思的歷史。人們總是在過去就做出未來需要的框架,而現(xiàn)在流行的是過去發(fā)明過的。如,響應(yīng)式設(shè)計(jì)不得不提到的一個(gè)缺點(diǎn)是:它只是將原本在模板層做的事,放到了樣式(CSS)層來完成。復(fù)雜度同力一樣不會(huì)消失,也不會(huì)憑空產(chǎn)生,它總是從一個(gè)物體轉(zhuǎn)移到另一個(gè)物體或一種形式轉(zhuǎn)為另一種形式。如果六、七年前的移動(dòng)網(wǎng)絡(luò)速度和今天一樣快,那么直接上的技術(shù)就是響應(yīng)式設(shè)計(jì),APP、SPA就不會(huì)流行得這么快。盡管我們可以預(yù)見未來這些領(lǐng)域會(huì)變得更好,但是更需要的是改變現(xiàn)狀。改變現(xiàn)狀的同時(shí)也需要預(yù)見未來的需求。(題圖來自:)什么是前端?維基百科是這樣說

2、的:前端(front-end)和后端(back-end)是描述進(jìn)程開始和結(jié)束的通用詞匯。前端作用于采集輸入信息,后端進(jìn)行處理。計(jì)算機(jī)程序的界面樣式,視覺呈現(xiàn)屬于前端。這種說法給人一種很模糊的感覺,但是他說得又很對(duì),它負(fù)責(zé)視覺展示。在MVC結(jié)構(gòu)或者M(jìn)VP中,負(fù)責(zé)視覺顯示的部分只有view層,而今天大多數(shù)所謂的View層已經(jīng)超越了View層。前端是一個(gè)很神奇的概念,但是而今的前端已經(jīng)發(fā)生了很大的變化。你引入了Backbone、Angluar,你的架構(gòu)變成了MVP、MVVM。盡管發(fā)生了一些架構(gòu)上的變化,但是項(xiàng)目的開發(fā)并沒有因此而發(fā)生變化。這其中涉及到了一些職責(zé)的問題,如果某一個(gè)層級(jí)中有太多的職責(zé),那

3、么它是不是加重了一些人的負(fù)擔(dān)?前端演進(jìn)史過去一直想整理一篇文章來說說前端發(fā)展的歷史,但是想著這些歷史已經(jīng)被人們所熟知。后來發(fā)現(xiàn)并非如此,大抵是幸存者偏見關(guān)注到的都知道這些歷史。數(shù)據(jù)-模板-樣式混合在有限的前端經(jīng)驗(yàn)里,我還是經(jīng)歷了那段用Table來作樣式的年代。大學(xué)期間曾經(jīng)有償幫一些公司或者個(gè)人開發(fā)、維護(hù)一些CMS,而Table是當(dāng)時(shí) 幫某個(gè)網(wǎng)站更新樣式接觸到的ASP.Net(maybe)。當(dāng)時(shí),我們啟動(dòng)這個(gè)CMS用的是一個(gè)名為aspweb.exe的程序。于是,在我的移動(dòng)硬 盤里找到了下面的代碼。1. <TABLE cellSpacing=0 cellPadding=0

4、 width=910 align=center border=0> 2.   <TBODY> 3.   <TR> 4.     <TD vAlign=top width=188><TABLE cellSpacing=0 cellPadding=0 width=184 align=center border=0> 5. 

5、60;       <TBODY> 6.         <TR> 7.           <TD>站外圖片上傳中(9)</TD></TR> 8.         <TR&

6、gt; 9.           <TD> 10.             <TABLE cellSpacing=0 cellPadding=0 width=184 align=center 11.        

7、0;    background=Images/xxx.gif border=0> 雖然,我也已經(jīng)在HEAD里找到了現(xiàn)代的雛形DIV + CSS,然而這仍然是一個(gè)Table的年代。<LINK href="img/xxx.css" type=text/css rel=stylesheet>人們一直在說前端很難,問題是你學(xué)過么?人們一直在說前端很難,問題是你學(xué)過么?人們一直在說前端很難,問題是你學(xué)過么?也許,你也一直在說CSS不好寫,但是CSS真的不好寫么?人們總在說JS很難用,但是你學(xué)過么?只在需要

8、的時(shí)候才去學(xué),那肯定很難。你不曾花時(shí)間去學(xué)習(xí)一門語言,但是卻能直接寫出可以work的代碼,說明他們?nèi)菀咨鲜?。如果你看過一些有經(jīng)驗(yàn)的Ruby、Scala、Emacs Lisp開發(fā)者寫出來的代碼,我想會(huì)得到相同的結(jié)論。有一些語言可以讓寫程序的人Happy,但是看的人可能就不Happy了。做事的方法不止一種,但是不是所有的人都要用那種方法去做。過去的那些程序員都是真正的全棧程序員,這些程序員不僅僅做了前端的活,還做了數(shù)據(jù)庫(kù)的工作。1. Set rs = Server.CreateObject("ADODB.Recordset") 2. sq

9、l = "select id,title,username,email,qq,adddate,content,Re_content,home,face,sex from Fl_Book where ispassed=1 order by id desc" 3. rs.open sql, Conn, 1, 1 4. fl.SqlQueryNum = fl.SqlQueryNum 

10、+ 1 在這個(gè)ASP文件里,它從數(shù)據(jù)庫(kù)里查找出了數(shù)據(jù),然后Render出HTML。如果可以看到歷史版本,那么我想我會(huì)看到有一個(gè)作者將style=”"的代碼一個(gè)個(gè)放到css文件中。在這里的代碼里也免不了有動(dòng)態(tài)生成JavaScript代碼的方法:show_other = "<SCRIPT language=javascript>"show_other = show_other & "function checkform()"show_other = show_other & ""s

11、how_other = show_other & "if (document.add.title.value='')"show_other = show_other & ""請(qǐng)盡情嘲笑,然后再看一段代碼:1. import React from "react" 2. import  getData  from "././common/request" 3. import st

12、yles from "./style.css" 4.  5. export default class HomePage extends React.Component  6.   componentWillMount()  7.     console.log("HomePage will mount with server 

13、response: ", ps.data.home); 8.    9.  10.   render()  11.     let  title  = ps.data.home; 12.  13.     return ( 14.     

14、;  <div className=styles.content> 15.         <h1>title</h1> 16.         <p className=styles.welcomeText>Thanks for joining!</p> 17.   

15、    </div> 18.     ); 19.    20.  21.   static fetchData = function(params)  22.     return getData("/home"); 23.    24.  10年前和10

16、年后的代碼,似乎沒有太多的變化。有所不同的是數(shù)據(jù)層已經(jīng)被獨(dú)立出去了,如果你的component也混合了數(shù)據(jù)層,即直接查詢數(shù)據(jù) 庫(kù)而不是調(diào)用數(shù)據(jù)層接口,那么你就需要好好思考下這個(gè)問題。你只是在追隨潮流,還是在改變。用一個(gè)View層更換一個(gè)View層,用一個(gè)Router換一 個(gè)Router的意義在哪?Model-View-Controller人們?cè)诓粩嗟胤此歼@其中復(fù)雜的過程,整理了一些好的架構(gòu)模式,其中不得不提到的是我司Martin Folwer的企業(yè)應(yīng)用架構(gòu)模式。該書中文譯版出版的時(shí)候是2004年,那時(shí)對(duì)于系統(tǒng)的分層是層次職責(zé)表現(xiàn)層提供服務(wù)、顯示信息、用戶請(qǐng)求、HTTP請(qǐng)求和命令行調(diào)用。領(lǐng)域?qū)舆?/p>

17、輯處理,系統(tǒng)中真正的核心。數(shù)據(jù)層與數(shù)據(jù)庫(kù)、消息系統(tǒng)、事物管理器和其他軟件包通訊?;碛诋?dāng)時(shí)最流行的Spring,就是MVC。人們有了iBatis這樣的數(shù)據(jù)持久層框架,即ORM,對(duì)象關(guān)系映射。于是,你的package就會(huì)有這樣的幾個(gè)文件夾:|_mappers|_model|_service|_utils|_controller在mappers這一層,我們所做的莫過于如下所示的數(shù)據(jù)庫(kù)相關(guān)查詢:1. Insert( 2.         "INSERT INTO users(use

18、rname, password, enabled) " + 3.                 "VALUES (#userName, #passwordHash, #enabled)" 4. ) 5. Options(keyProperty = "id", 

19、;keyColumn = "id", useGeneratedKeys = true) 6. void insert(User user); model文件夾和mappers文件夾都是數(shù)據(jù)層的一部分,只是兩者間的職責(zé)不同,如:1. public String getUserName()  2.     return userName; 3.  4.  5. publi

20、c void setUserName(String userName)  6.     this.userName = userName; 7.  而他們最后都需要在Controller,又或者稱為ModelAndView中處理:1. RequestMapping(value = "/disableUser", method = RequestMethod.POST) 2. public

21、 ModelAndView processUserDisable(HttpServletRequest request, ModelMap model)  3.     String userName = request.getParameter("userName"); 4.     User user = userService.getByUsernam

22、e(userName); 5.     userService.disable(user); 6.     Map<String,User> map = new HashMap<String,User>(); 7.     Map <User,String> usersWithRoles= userService.getAllUsersWit

23、hRole(); 8.     model.put("usersWithRoles",usersWithRoles); 9.     return new ModelAndView("redirect:users",map); 10.  在多數(shù)時(shí)候,Controller不應(yīng)該直接與數(shù)據(jù)層的一部分,而將業(yè)務(wù)邏輯放在Controller層又是一種錯(cuò)誤,這時(shí)就有了Service層,如下圖:Service MVC然而對(duì)于Do

24、main相關(guān)的Service應(yīng)該放在哪一層,總會(huì)有不同的意見:MVC PlayerMS MVCDomain(業(yè)務(wù))是一個(gè)相當(dāng)復(fù)雜的層級(jí),這里是業(yè)務(wù)的核心。一個(gè)合理的Controller只應(yīng)該做自己應(yīng)該做的事,它不應(yīng)該處理業(yè)務(wù)相關(guān)的代碼:1. if (isNewnameEmpty = false && newuser = null) 2.     user.setUserName(newUsername); 3.    &

25、#160;List<Post> myPosts = postService.findMainPostByAuthorNameSortedByCreateTime(principal.getName(); 4.  5.     for (int k = 0;k < myPosts.size();k+) 6.         Post 

26、;post = myPosts.get(k); 7.         post.setAuthorName(newUsername); 8.         postService.save(post); 9.      10.     userService.update(user); 

27、11.     Authentication oldAuthentication = SecurityContextHolder.getContext().getAuthentication(); 12.     Authentication authentication = null; 13.     if(oldAuthentication = null) 14.

28、         authentication = new UsernamePasswordAuthenticationToken(newUsername,user.getPasswordHash(); 15.     else 16.         authentication = new UsernamePass

29、wordAuthenticationToken(newUsername,user.getPasswordHash(),oldAuthentication.getAuthorities(); 17.      18.     SecurityContextHolder.getContext().setAuthentication(authentication); 19.     map.clear(); 20.   &

30、#160; map.put("user",user); 21.     model.addAttribute("myPosts", myPosts); 22.     model.addAttribute("namesuccess", "User Profile updated successfully"); 23.   

31、60; return new ModelAndView("user/profile", map); 24.  我們?cè)贑ontroller層應(yīng)該做的事是:· 處理請(qǐng)求的參數(shù)· 渲染和重定向· 選擇Model和Service· 處理Session和Cookies業(yè)務(wù)是善變的,昨天我們可能還在和對(duì)手競(jìng)爭(zhēng)誰先推出新功能,但是今天可能已經(jīng)合并了。我們很難預(yù)見業(yè)務(wù)變化,但是我們應(yīng)該能預(yù)見Controller是不容易變化的。在一些設(shè)計(jì)里面,這種模式就是Command模式。View層是一直在

32、變化的層級(jí),人們的品味一直在更新,有時(shí)甚至可能因?yàn)楦?jìng)爭(zhēng)對(duì)手而產(chǎn)生變化。在已經(jīng)取得一定市場(chǎng)的情況下,Model- Service-Controller通常都不太會(huì)變動(dòng),甚至不敢變動(dòng)。企業(yè)意識(shí)到創(chuàng)新的兩面性,要么帶來死亡,要么占領(lǐng)更大的市場(chǎng)。但是對(duì)手通常都比你 想象中的更聰明一些,所以這時(shí)開創(chuàng)新的業(yè)務(wù)是一個(gè)更好的選擇。高速發(fā)展期的企業(yè)和發(fā)展初期的企業(yè)相比,更需要前端開發(fā)人員。在用戶基數(shù)不夠、業(yè)務(wù)待定的情形中,View只要可用并美觀就行了,這時(shí)可能就會(huì)有大量的業(yè)務(wù)代碼放在View層:1. <c:choose> 2.     <c:w

33、hen test="$ hasError "> 3.     <p class="prompt-error"> 4.         $errors.username $errors.password 5.     </p> 6.     

34、</c:when> 7.     <c:otherwise> 8.     <p class="prompt"> 9.         Woohoo, User <span class="username">$user.userName</span> has&

35、#160;been created successfully! 10.     </p> 11.     </c:otherwise> 12. </c:choose> 不同的情形下,人們都會(huì)對(duì)此有所爭(zhēng)議,但只要符合當(dāng)前的業(yè)務(wù)便是最好的選擇。作為一個(gè)前端開發(fā)人員,在過去我需要修改JSP、PHP文件,這期間我需要去了解這些Template:1. foreach $lists as $v 

36、;2. <li itemprop="breadcrumb"><spanif(newest($v'addtime',24) style="color:red"/if>fun date('Y-m-d',$v'addtime')</span><a href="$v'url'" style="$v'style'" target="_b

37、lank">$v'title'</a></li> 3. /foreach 有時(shí)像Django這一類,自稱為Model-Template-View的框架,更容易讓人理解其意圖:1. % for blog_post in blog_posts.object_list % 2. % block blog_post_list_post_title % 3. <section class="section

38、-center mdl-grid mdl-grid-no-spacing mdl-shadow-2dp mdl-cell-11-col blog-list"> 4. % editable blog_post.title % 5. <div class="mdl-card_title mdl-card-border mdl-card-expand"> 6.     <

39、;h2 class="mdl-card_title-text"> 7.         <a href=" blog_post.get_absolute_url "  itemprop="headline"> blog_post.title   </a> 8.     

40、</h2> 9. </div> 10. % endeditable % 11. % endblock % 作為一個(gè)前端人員,我們真正在接觸的是View層和Template層,但是MVC并沒有說明這些。從桌面版到移動(dòng)版Wap出現(xiàn)了,并帶來了更多的挑戰(zhàn)。隨后,分辨率從1024×768變成了176×208,開發(fā)人員不得不面臨這些挑戰(zhàn)。當(dāng)時(shí)所需要做的僅僅是修改View層,而View層隨著iPhone的出現(xiàn)又發(fā)生了變化。WAP 網(wǎng)站這是一個(gè)短暫的歷史,PO還需要為手機(jī)用戶制作一個(gè)怎

41、樣的網(wǎng)站?于是他們把桌面版的網(wǎng)站搬了過去變成了移動(dòng)版。由于網(wǎng)絡(luò)的原因,每次都需要重新加載頁(yè)面,這帶來了不佳的用戶體驗(yàn)。幸運(yùn)的是,人們很快意識(shí)到了這個(gè)問題,于是就有了SPA。如果當(dāng)時(shí)的移動(dòng)網(wǎng)絡(luò)速度可以更快的話,我想很多SPA框架就不存在了。先說說jQuery Mobile,在那之前,先讓我們來看看兩個(gè)不同版本的代碼,下面是一個(gè)手機(jī)版本的blog詳情頁(yè):1. <ul data-role="listview" data-inset="true" data-splittheme="a"> 2

42、.     % for blog_post in blog_posts.object_list % 3.         <li> 4.         % editable blog_post.title blog_post.publish_date % 5. &#

43、160;       <h2 class="blog-post-title"><a href="% url "blog_post_detail" blog_post.slug %"> blog_post.title </a></h2> 6.        

44、60;<em class="since">% blocktrans with sometime=blog_post.publish_date|timesince % sometime  ago% endblocktrans %</em> 7.         % endeditable % 8.    &

45、#160;    </li> 9.     % endfor % 10. </ul> 而下面是桌面版本的片段:1. % for blog_post in blog_posts.object_list % 2. % block blog_post_list_post_title % 3. % editable blog_pos

46、t.title % 4. <h2> 5.     <a href=" blog_post.get_absolute_url "> blog_post.title </a> 6. </h2> 7. % endeditable % 8. % endblock % 9. % block blog_post_list_

47、post_metainfo % 10. % editable blog_post.publish_date % 11. <h6 class="post-meta"> 12.     % trans "Posted by" %: 13.     % with blog_post.user as au

48、thor % 14.     <a href="% url "blog_post_list_author" author %"> author.get_full_name|default:author.username </a> 15.     % endwith % 16.     

49、% with blog_post.categories.all as categories % 17.     % if categories % 18.     % trans "in" % 19.     % for category in categories %

50、 20.     <a href="% url "blog_post_list_category" category.slug %"> category </a>% if not forloop.last %, % endif % 21.     % endfor %

51、0;22.     % endif % 23.     % endwith % 24.     % blocktrans with sometime=blog_post.publish_date|timesince % sometime  ago% endblocktrans % 25. </h6>

52、0;26. % endeditable % 27. % endblock % 人們所做的只是重載View層。這也是一個(gè)有效的SEO策略,上面這些代碼是我博客過去的代碼。對(duì)于桌面版和移動(dòng)版都是不同的模板和不同的JS、CSS。移動(dòng)版網(wǎng)頁(yè)在這一時(shí)期,桌面版和移動(dòng)版的代碼可能在同一個(gè)代碼庫(kù)中。他們使用相同的代碼,調(diào)用相同的邏輯,只是View層不同了。但是,每次改動(dòng)我們都要維護(hù)兩份代碼。隨后,人們發(fā)現(xiàn)了一種更友好的移動(dòng)版應(yīng)用APP。APP與過渡期API這是一個(gè)艱難的時(shí)刻,過去我們的很多API都是在原來的代碼庫(kù)中構(gòu)建的,即桌面版和移動(dòng)版一起。我們

53、已經(jīng)在這個(gè)代碼庫(kù)中開發(fā)了越來越多的功能,系統(tǒng)開發(fā)變得臃腫。如Linux/Unix設(shè)計(jì)思想中所說,這是一個(gè)偉大的系統(tǒng),但是它臃腫而又緩慢。我們是選擇重新開發(fā)一個(gè)結(jié)合第一和第二系統(tǒng)的最佳特性的第三個(gè)系統(tǒng),還是繼續(xù)臃腫下去。我想你已經(jīng)有答案了。隨后我們就有了APP API,構(gòu)建出了博客的APP。應(yīng)用最開始,人們?cè)絹碓较矚g用APP,因?yàn)榕c移動(dòng)版網(wǎng)頁(yè)相比,其響應(yīng)速度更快,而且更流暢。對(duì)于服務(wù)器來說,也是一件好事,因?yàn)檎?qǐng)求變少了。但是并非所有的人都會(huì)下載APP有時(shí)只想看看上面有沒有需要的東西。對(duì)于剛需不強(qiáng)的應(yīng)用,人們并不會(huì)下載,只會(huì)訪問網(wǎng)站。有了APP API之后,我們可以向網(wǎng)頁(yè)提供API,我們就開始設(shè)想

54、要有一個(gè)好好的移動(dòng)版。過渡期SPABackbone誕生于2010年,和響應(yīng)式設(shè)計(jì)出現(xiàn)在同一個(gè)年代里,但他們似乎在同一個(gè)時(shí)代里火了起來。如果CSS3早點(diǎn)流行開來,似乎就沒有Backbone啥事了。不過移動(dòng)網(wǎng)絡(luò)還是限制了響應(yīng)式的流行,只是在今天這些都有所變化。我們用Ajax向后臺(tái)請(qǐng)求API,然后Mustache Render出來。因?yàn)镴avaScript在模塊化上的缺陷,所以我們就用Require.JS來進(jìn)行模塊化。下面的代碼就是我在嘗試對(duì)我的博客進(jìn)行SPA設(shè)計(jì)時(shí)的代碼:1. define( 2.     'zepto', 

55、;3.     'underscore', 4.     'mustache', 5.     'js/ProductsView', 6.     'json!/configure.json', 7.     'text!/templates/blog_details.html'

56、, 8.     'js/renderBlog' 9. ,function($, _, Mustache, ProductsView, configure, blogDetailsTemplate, GetBlog) 10.  11.     var BlogDetailsView = Backbone.View.extend ( 12.  

57、       el: $("#content"), 13.  14.         initialize: function ()  15.             this.params = '#conten

58、t' 16.         , 17.  18.         getBlog: function(slug)  19.             var getblog = new GetBlog(this.

59、params, configure'blogPostUrl' + slug, blogDetailsTemplate); 20.             getblog.renderBlog(); 21.          22.     ); 23.  

60、;24.     return BlogDetailsView; 25. ); 從API獲取數(shù)據(jù),結(jié)合Template來Render出Page。但是這無法改變我們需要Client Side Render和Server Side Render的兩種Render方式,除非我們可以像淘寶一樣不需要考慮SEO因?yàn)樗荒敲匆揽克阉饕鎺砹髁俊_@時(shí),我們還是基于類MVC模式。只是數(shù)據(jù)的獲取方式變成了Ajax,我們就犯了一個(gè)錯(cuò)誤將大量的業(yè)務(wù)邏輯放在前端。這時(shí)候我們已經(jīng)不能再?gòu)腣iew層直接訪問Model層,從安全的角度來說有點(diǎn)危險(xiǎn)。如果

61、你的View層還可以直接訪問Model層,那么說明你的架構(gòu)還是MVC模式。之前我在Github上構(gòu)建一個(gè)Side Project的時(shí)候直接用View層訪問了Model層,由于Model層是一個(gè)ElasticSearch的搜索引擎,它提供了JSON API,這使得我要在View層處理數(shù)據(jù)即業(yè)務(wù)邏輯。將上述的JSON API放入Controller,盡管會(huì)加重這一層的復(fù)雜度,但是業(yè)務(wù)邏輯就不再放置于View層。如果你在你的View層和Model層總有一層接口,那么你采用的就是MVP模式MVC模式的衍生(PS:為了區(qū)別別的事情,總會(huì)有人取個(gè)表意的名稱)。一夜之前,我們又回到了過去。我們離開了JSP,

62、將View層變成了Template與Controller。而原有的Services層并不是只承擔(dān)其原來的責(zé)任,這些Services開始向ViewModel改變。一些團(tuán)隊(duì)便將Services抽成多個(gè)Services,美其名為微服務(wù)。傳統(tǒng)架構(gòu)下的API從下圖API Gateway變成了直接調(diào)用的微服務(wù):Micro Services對(duì)于后臺(tái)開發(fā)者來說,這是一件大快人心的大好事,但是對(duì)于應(yīng)用端/前端來說并非如此。調(diào)用的服務(wù)變多了,在應(yīng)用程序端進(jìn)行功能測(cè)試變得更復(fù)雜,需要Mock的API變多了。Hybird與ViewModel這時(shí)候遇到問題的不僅僅只在前端,而在App端,小的團(tuán)隊(duì)已經(jīng)無法承受開發(fā)成本。人

63、們更多的注意力放到了Hybird應(yīng)用上。Hybird應(yīng)用解決了一些小團(tuán)隊(duì)在開發(fā)初期遇到的問題,這部分應(yīng)用便交給了前端開發(fā)者。前端開發(fā)人員先熟悉了單純的JS + CSS + HTML,又熟悉了Router + PageView + API的結(jié)構(gòu),現(xiàn)在他們又需要做手機(jī)APP。這時(shí)候只好用熟悉的jQuer Mobile + Cordova。隨后,人們先從Cordova + jQuery Mobile,變成了Cordova + Angular的 Ionic。在那之前,一些團(tuán)隊(duì)可能已經(jīng)用Angular代換了Backbone。他們需要更好的交互,需要data binding。接著,我們可以直接將我們的An

64、gular代碼從前端移到APP,比如下面這種博客APP的代碼: 1. .controller('BlogCtrl', function ($scope, Blog)  2.   $scope.blogs = null; 3.   $scope.blogOffset = 0; 4.   / 5.   $scope.doRefresh = function

65、 ()  6.     Blog.async('7.       $scope.blogs = results.objects; 8.     ); 9.     $scope.$broadcast('scroll.refreshComplete'); 10.     $scope.$apply() 11.    12.  13.   Blog.async('14.     $scope.blogs = results.objects; 15.   ); 16.  17.   $scope.loadMo

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論