鑰匙要點
-
AngularJ中的
- 查看模型可以具有僅限客戶端狀態,例如“動畫啟動”和“動畫”或“拖動”和“刪除”。使用Angular的$ Resource Service創建和保存視圖模型時,可以管理此狀態。
> >將狀態變化邏輯封裝在一個地方,例如注射服務,可以簡化代碼並減少錯誤,尤其是對於具有多重消費者的應用程序。
- >諸如功能包裝之類的技術可用於保存和檢索數據之前和之後進行不同或其他的事情。這可以增強$ Resource Service的功能。
- >將視圖模型提取到注射服務中可以幫助擴展應用程序,尤其是具有復雜,實時更新的應用程序。觀看和過濾等技術可用於管理狀態變化並改善應用程序API的合成性。
- JavaScript框架(例如AngularJs)中的 >查看模型可能與服務器上的域模型不同 - 視圖模型甚至不必在服務器上存在。因此,視圖模型只能具有客戶端狀態,例如“動畫開始”和“動畫”或“拖動”和“掉落”。這篇文章使用Angular的$ Resource Service創建和保存視圖模型時將集中於狀態更改。
這種方法對於包含單個消費者的應用程序很好。想像一下,對於多個消費者,容易複製此代碼的無聊和錯誤!但是,如果我們可以封裝狀態在一個地方更改邏輯怎麼辦?
>angular<span>.module('clientOnlyState.controllers') </span> <span>.controller('ArticleCtrl', function($scope, $resource, ArticleStates /* simple lookup */) { </span> <span>var Article = $resource('/article/:articleId', { articleId: '@id' }); </span> <span>var article = new Article({ id: 1, title: 'A title', author: 'M Godfrey' }); </span> article<span>.state = ArticleStates.NONE; // "NONE" </span> $scope<span>.article = article; </span> $scope<span>.save = function() { </span> article<span>.state = ArticleStates.SAVING; // "SAVING" </span> article<span>.$save(function success() { </span> article<span>.state = ArticleStates.SAVED; // "SAVED" </span> <span>}); </span> <span>}; </span> <span>});</span>$ Resource Services
>讓我們從將我們的文章資源推入註射服務中。當首次創建文章時,我們還將最微不足道的狀態設置添加到無。
檢索和保存怎麼樣?我們希望將文章作為$資源服務出現在消費者身上,因此它必須像一個人一樣始終如一地工作。我在John Resig的出色著作《 JavaScript Ninja的秘密》中學到的一種技術在這裡非常有用 - 功能包裝。這是他的實現直接提升為可注射的角度服務。
>
angular<span>.module('clientOnlyState.services') </span> <span>.factory('Article', function($resource<span>, ArticleStates</span>) { </span> <span>var Article = $resource('/article/:articleId', { articleId: '@id' }); </span> <span>// Consumers will think they're getting an Article instance, and eventually they are... </span> <span>return function(data) { </span> <span>var article = new Article(data); </span> article<span>.state = ArticleStates.NONE; </span> <span>return article; </span> <span>} </span> <span>});</span>>這使我們能夠包裝保存並獲取文章的方法,並在之前和之後做一些不同/其他的事情:
angular<span>.module('clientOnlyState.services') </span> <span>.factory('wrapMethod', function() { </span> <span>return function(object<span>, method, wrapper</span>) { </span> <span>var fn = object[method]; </span> <span>return object[method] = function() { </span> <span>return wrapper.apply(this, [fn.bind(this)].concat( </span> <span>Array.prototype.slice.call(arguments)) </span> <span>); </span> <span>}; </span> <span>} </span> <span>});</span>>我們的控制器由於此而開始變得更加傾斜,並且完全不知道如何設置狀態。這很好,因為控制器也不應該在乎。
>
angular<span>.module('clientOnlyState.controllers') </span> <span>.controller('ArticleCtrl', function($scope, $resource, ArticleStates /* simple lookup */) { </span> <span>var Article = $resource('/article/:articleId', { articleId: '@id' }); </span> <span>var article = new Article({ id: 1, title: 'A title', author: 'M Godfrey' }); </span> article<span>.state = ArticleStates.NONE; // "NONE" </span> $scope<span>.article = article; </span> $scope<span>.save = function() { </span> article<span>.state = ArticleStates.SAVING; // "SAVING" </span> article<span>.$save(function success() { </span> article<span>.state = ArticleStates.SAVED; // "SAVED" </span> <span>}); </span> <span>}; </span> <span>});</span>
封裝益處
>我們已經竭盡全力封裝了控制器之外的狀態變化,但是我們獲得了什麼好處?
>現在,我們的控制器可以利用通過舊狀態通過的手錶聽眾來設置消息。它也可以執行本地翻譯,如下所示。
angular<span>.module('clientOnlyState.services') </span> <span>.factory('Article', function($resource<span>, ArticleStates</span>) { </span> <span>var Article = $resource('/article/:articleId', { articleId: '@id' }); </span> <span>// Consumers will think they're getting an Article instance, and eventually they are... </span> <span>return function(data) { </span> <span>var article = new Article(data); </span> article<span>.state = ArticleStates.NONE; </span> <span>return article; </span> <span>} </span> <span>});</span>考慮$ scopes,指令和過濾器構成應用程序的API。 HTML視圖消耗此API。 API的合成性越大,重用的潛力就越大。過濾器可以改善新觀看與舊觀看的合成性嗎?
通過濾鏡組合,靈丹妙藥?
>
>類似以下內容是我的想法。表達的每個部分都可以重複使用。
angular<span>.module('clientOnlyState.services') </span> <span>.factory('wrapMethod', function() { </span> <span>return function(object<span>, method, wrapper</span>) { </span> <span>var fn = object[method]; </span> <span>return object[method] = function() { </span> <span>return wrapper.apply(this, [fn.bind(this)].concat( </span> <span>Array.prototype.slice.call(arguments)) </span> <span>); </span> <span>}; </span> <span>} </span> <span>});</span>從Angular 1.3開始,過濾器可以使用$ stateful屬性,但是由於Angular無法根據輸入參數的值調用過濾器,因此強烈勸阻其使用。因此,我們將將狀態參數傳遞給Limittotransition(以前的狀態)並翻譯(可用翻譯)。
因此,我們需要對文章進行稍作修改:
angular<span>.module('clientOnlyState.services') </span> <span>.factory('Article', function($resource<span>, ArticleStates, wrapMethod</span>) { </span> <span>var Article = $resource('/article/:articleId', { articleId: '@id' }); </span> <span>wrapMethod(Article, 'get', function(original<span>, params</span>) { </span> <span>var article = original(params); </span> article<span>.$promise.then(function(article) { </span> article<span>.state = ArticleStates.NONE; </span> <span>}); </span> <span>return article; </span> <span>}); </span> <span>// Consumers will actually call $save with optional params, success and error arguments </span> <span>// $save consolidates arguments and then calls our wrapper, additionally passing the Resource instance </span> <span>wrapMethod(Article, 'save', function(original<span>, params, article, success, error</span>) { </span> article<span>.state = ArticleStates.SAVING; </span> <span>return original.call(this, params, article, function (article) { </span> article<span>.state = ArticleStates.SAVED; </span> success <span>&& success(article); </span> <span>}, function(article) { </span> article<span>.state = ArticleStates.ERROR; </span> error <span>&& error(article); </span> <span>}); </span> <span>}); </span> <span>// $resource(...) returns a function that also has methods </span> <span>// As such we reference Article's own properties via extend </span> <span>// Which in the case of get and save are already wrapped functions </span> <span>return angular.extend(function(data) { </span> <span>var article = new Article(data); </span> article<span>.state = ArticleStates.NONE; </span> <span>return article; </span> <span>}, Article); </span> <span>});</span>>
最終結果並不那麼漂亮,但仍然非常強大:
angular<span>.module('clientOnlyState.controllers') </span> <span>.controller('ArticleCtrl', function($scope<span>, Article</span>) { </span> <span>var article = new Article({ id: 1, title: 'A title', author: 'M Godfrey' }); </span> <span>console.log(article.state); // "NONE" </span> $scope<span>.article = article; </span> $scope<span>.save = function() { </span> article<span>.$save({}, function success() { </span> <span>console.log(article.state); // "SAVED" </span> <span>}, function error() { </span> <span>console.log(article.state); // "ERROR" </span> <span>}); </span> <span>}; </span> <span>});</span>
我們的控制器再次變得更傾斜,尤其是如果您認為可以將翻譯拉出到可注射的服務中:
angular<span>.module('clientOnlyState.controllers') </span> <span>.controller('ArticleCtrl', function($scope<span>, Article, ArticleStates</span>) { </span> <span>var article = new Article({ id: 1, title: 'A title', author: 'M Godfrey' }); </span> <span>var translations = {}; </span> translations<span>[ArticleStates.SAVED] = 'Saved, oh yeah!'; </span> translations<span>['default'] = ''; </span> $scope<span>.article = article; </span> $scope<span>.save = function() { </span> article<span>.$save({}); </span> <span>}; </span> $scope<span>.$watch('article.state', function(newState<span>, oldState</span>) { </span> <span>if (newState == ArticleStates.SAVED && oldState == ArticleStates.SAVING) { </span> $scope<span>.message = translations[newState]; </span> <span>} else { </span> $scope<span>.message = translations['default']; </span> <span>} </span> <span>}); </span> <span>});</span>
結論
<span><span><span><p>></p></span>{{article.state | limitToTransition:"SAVING":"SAVED" | translate}}<span><span></span>></span></span></span>>將視圖模型提取到注射服務中有助於我們擴展應用程序。這篇文章中給出的示例很簡單。考慮一個允許貨幣對交易的應用程序(例如,英鎊至USD,EUR到GBP等)。每個貨幣對代表一個產品。在這樣的應用程序中,可能會有數百種產品,每種產品都會收到實時價格更新。價格更新可能高於當前價格。該應用程序的一部分可能會關心連續兩次更高的價格,而另一部分可能關心剛剛降低的價格。能夠觀察這些價格變化狀態極大地簡化了應用程序的各個部分。
>我提出了一種基於舊值和新值觀察的替代方法。兩者都是完全可以接受的技術 - 實際上,當我開始研究這篇文章時,我想到的是我的想法。過濾是在完成後附近發現的潛在改進。
>我很想看看我提出的技術是否可以幫助您擴展Angular應用程序。所有反饋都將在評論中得到極大的收穫!
>在研究此帖子時創建的代碼樣本也可以在GitHub上找到。
>在Angularjs中管理客戶狀態的經常詢問的問題
> $ state -provider在AngularJS中管理客戶端狀態的作用是什麼?這是一項允許您為應用程序定義狀態的服務。每個狀態就整體UI和導航而言,對應於應用程序中的“位置”。 $ state -provider提供了路由不同視圖的API。激活狀態時,它可以通過Resolve屬性解析一組數據。然後將這些數據注入控制器。 >>我如何在$ state -provider中使用resolve屬性?用於在激活狀態之前解決一組數據。然後將這些數據注入控制器。解析屬性是包含鍵值對的對象。關鍵是要注入控制器的依賴項的名稱,該值是返回依賴關係值的函數。
>在Angularjs中使用UI-Router進行狀態管理有什麼好處?它允許嵌套視圖和多個命名視圖,這在較大的應用程序中可能非常有用。它還提供了基於狀態的路由,它比AngularJS中的基於默認路由的路由更靈活,更強大。
>我如何在gangularjs中的狀態之間過渡?在AngularJS中使用$ state.go()方法。該方法將狀態的名稱作為其第一個參數,而參數的可選對像是其第二個參數。參數對象可用於將數據傳遞到要過渡到的狀態。
我可以在沒有狀態管理工具的情況下使用AngularJS嗎?但是,隨著您的應用程序的複雜性增長,如果使用UI-Router這樣的工具,管理狀態可能會變得越來越困難。使用狀態管理工具可以幫助維持應用程序用戶界面的一致性和可預測性。
>>在AngularJS中管理狀態的一些共同挑戰是什麼?保持用戶界面的一致性,跟踪應用程序狀態的變化以及管理應用程序的行為。通過使用UI-Router等狀態管理工具。
>我如何在$ state -provider中使用resolve屬性?用於在激活狀態之前解決一組數據。然後將這些數據注入控制器。解析屬性是包含鍵值對的對象。關鍵是要注入控制器的依賴項的名稱,該值是返回依賴關係值的函數。
>在Angularjs中使用UI-Router進行狀態管理有什麼好處?它允許嵌套視圖和多個命名視圖,這在較大的應用程序中可能非常有用。它還提供了基於狀態的路由,它比AngularJS中的基於默認路由的路由更靈活,更強大。
>我如何在gangularjs中的狀態之間過渡?在AngularJS中使用$ state.go()方法。該方法將狀態的名稱作為其第一個參數,而參數的可選對像是其第二個參數。參數對象可用於將數據傳遞到要過渡到的狀態。
我可以在沒有狀態管理工具的情況下使用AngularJS嗎?但是,隨著您的應用程序的複雜性增長,如果使用UI-Router這樣的工具,管理狀態可能會變得越來越困難。使用狀態管理工具可以幫助維持應用程序用戶界面的一致性和可預測性。
>>在AngularJS中管理狀態的一些共同挑戰是什麼?保持用戶界面的一致性,跟踪應用程序狀態的變化以及管理應用程序的行為。通過使用UI-Router等狀態管理工具。
以上是在Angularjs管理僅限客戶狀態的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript字符串替換方法詳解及常見問題解答 本文將探討兩種在JavaScript中替換字符串字符的方法:在JavaScript代碼內部替換和在網頁HTML內部替換。 在JavaScript代碼內部替換字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 該方法僅替換第一個匹配項。要替換所有匹配項,需使用正則表達式並添加全局標誌g: str = str.replace(/fi

因此,在這裡,您準備好了解所有稱為Ajax的東西。但是,到底是什麼? AJAX一詞是指用於創建動態,交互式Web內容的一系列寬鬆的技術。 Ajax一詞,最初由Jesse J創造

10款趣味橫生的jQuery遊戲插件,讓您的網站更具吸引力,提升用戶粘性!雖然Flash仍然是開發休閒網頁遊戲的最佳軟件,但jQuery也能創造出令人驚喜的效果,雖然無法與純動作Flash遊戲媲美,但在某些情況下,您也能在瀏覽器中獲得意想不到的樂趣。 jQuery井字棋遊戲 遊戲編程的“Hello world”,現在有了jQuery版本。 源碼 jQuery瘋狂填詞遊戲 這是一個填空遊戲,由於不知道單詞的上下文,可能會產生一些古怪的結果。 源碼 jQuery掃雷遊戲

本教程演示瞭如何使用jQuery創建迷人的視差背景效果。 我們將構建一個帶有分層圖像的標題橫幅,從而創造出令人驚嘆的視覺深度。 更新的插件可與JQuery 1.6.4及更高版本一起使用。 下載

本文演示瞭如何使用jQuery和ajax自動每5秒自動刷新DIV的內容。 該示例從RSS提要中獲取並顯示了最新的博客文章以及最後的刷新時間戳。 加載圖像是選擇

本文討論了在瀏覽器中優化JavaScript性能的策略,重點是減少執行時間並最大程度地減少對頁面負載速度的影響。

Matter.js是一個用JavaScript編寫的2D剛體物理引擎。此庫可以幫助您輕鬆地在瀏覽器中模擬2D物理。它提供了許多功能,例如創建剛體並為其分配質量、面積或密度等物理屬性的能力。您還可以模擬不同類型的碰撞和力,例如重力摩擦力。 Matter.js支持所有主流瀏覽器。此外,它也適用於移動設備,因為它可以檢測觸摸並具有響應能力。所有這些功能都使其值得您投入時間學習如何使用該引擎,因為這樣您就可以輕鬆創建基於物理的2D遊戲或模擬。在本教程中,我將介紹此庫的基礎知識,包括其安裝和用法,並提供一


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

Dreamweaver Mac版
視覺化網頁開發工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具